Sunday, May 9, 2010

Type level success #2

I've long wanted to have an analogue to TikZ's "matrix" command in Wumpus. The matrix command introduces named nodes and blanks within a list of equal sized rows. To introduce new names, something monadic seemed good in Haskell; but I couldn't work out how to enforce that each row should have the same width - especially when I only wanted to bind names to nodes and not blanks.

Currently wumpus-extra has a doodle that doesn't even try to enforce row size, its just about useful as it tracks a coordinate space with a state monad - each new node gets attributed with its coordinate position from the current state and 1 gets added to the column number. The row command resets the column count and adds 1 to the row number.

Here's one with type level naturals measuring a snoc list that does enforce row width. Currently its via an Identity monad with an extra shape parameter. Hopefully it will extend to a state monad to track coordinates:


{-# LANGUAGE EmptyDataDecls #-}

module GridTemp03 where

data Z
data S a


newtype Id sh a = Id a

runId :: Id sh a -> a
runId (Id a) = a

instance Monad (Id sh) where
return a = Id a
Id a >>= f = Id $ (runId . f) a

nil :: Id Z ()
nil = Id ()

blank :: Id sh a -> Id (S sh) a
blank (Id acc) = Id acc

node :: Int -> Id sh a -> Id (S sh) (a,Int)
node i (Id acc) = Id (acc,i)

infixl 5 &
(&) :: Id sh a -> (Id sh a -> Id (S sh) b) -> Id (S sh) b
tl & h = h tl

elem0 :: Id sh () -> Id sh ()
elem0 (Id ()) = Id ()

elem1 :: Id sh ((),a) -> Id sh a
elem1 (Id ((),a)) = Id a

elem2 :: Id sh (((),a),b) -> Id sh (a,b)
elem2 (Id (((),a),b)) = Id (a,b)

elem3 :: Id sh ((((),a),b),c) -> Id sh (a,b,c)
elem3 (Id ((((),a),b),c)) = Id (a,b,c)

-- Rows must have the same width and the number of
-- nodes in the row content must match the respective
-- elemN function.
--
demo1 = runId $ do
r1 <- elem3 $ nil & node 1 & blank & node 2 & node 3
r2 <- elem0 $ nil & blank & blank & blank & blank
return (r1,r2)

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.