Friday, April 9, 2010

Type level success?

I've never had much success with type level programming, but maybe this new score representation for Neume means I'm improving (as the name indicates this particular one took seven attempts).

The shape of the score (linear sections, repeated sections, alternative endings), is encoded in the type. That the Show and Functor instance were easy to code indicates that the it might actually be useful. Previously when I've tried type level programming I've ended up with structures that I couldn't actually work with.




{-# LANGUAGE GADTs #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE TypeOperators #-}


module GADTSection7 where

data Z = Z

data x :. xs = x :. xs

data TLinear
data TRepeat
data TAltRep



data TList shape e where
Nil :: TList Z e
Linear :: e -> TList shape e -> TList (TLinear :. shape) e
Repeat :: e -> TList shape e -> TList (TRepeat :. shape) e
AltRep :: e -> [e] -> TList shape e -> TList (TAltRep :. shape) e

-- Good - shape of the list reflected in its type...


tune0 = Linear "...o..o" $ Nil



tune1 = Linear "....o..o" $ Linear "...o..o" $ Nil

tune2 = Repeat "o.o..o.o" $ Nil



-- Good - disallows junk...
-- tune3 = Linear "....o..o" $ Linear 3000 $ Nil



sameType :: TList sh e -> TList sh e -> Bool
sameType _ _ = True


-- Good - throws error...
-- > sametype tune1 tune2


tune4 = Repeat "........" $ Nil

demo01 = sameType tune2 tune4


tune5 = Linear "o.o....." $ Nil


-- Good ...
-- sameType enforces sameShape not just sameLength
-- demo02 = sameType tune4 tune5

sameShape :: TList sh e -> TList sh e' -> Bool
sameShape _ _ = True

tune6 = Linear 3000 $ Nil

demo03 = sameShape tune5 tune6

instance Functor (TList shape) where
fmap _ Nil = Nil
fmap f (Linear e xs) = Linear (f e) (fmap f xs)
fmap f (Repeat e xs) = Repeat (f e) (fmap f xs)
fmap f (AltRep e es xs) = AltRep (f e) (map f es) (fmap f xs)

instance Show e => Show (TList shape e) where
showsPrec _ Nil = showString "Nil"

showsPrec _ (Linear e xs) =
showString "Linear" . spS . shows e . spS . appS . spS . shows xs

showsPrec _ (Repeat e xs) =
showString "Repeat" . spS . shows e . spS . appS . spS . shows xs

showsPrec _ (AltRep e es xs) =
showString "AltRep" . spS . shows e . spS . showList es . spS
. appS . spS . shows xs


tune7 = AltRep "o.o.o..o" ["o.", ".o"] $ Nil

spS :: ShowS
spS = showChar ' '

appS :: ShowS
appS = showChar '$'

Blog Archive

About Me

My photo
Disambiguating biog as there are a few Stephen Tetley's in the world. I'm neither a cage fighter or yachtsman. I studied Fine Art in the nineties (foundation Bradford 1992, degree Cheltenham 1992 - 95) then Computing part-time at Leeds Met graduating in 2003. I'm the Stephen Tetley on Haskell Cafe and Stackoverflow.