[Haskell-cafe] state in the continuation monad...
Ralf Laemmel
Ralf.Laemmel at cwi.nl
Fri Jul 2 10:15:15 EDT 2004
-------------- next part --------------
{-# OPTIONS -fglasgow-exts #-}
{-
Regarding Keean's posting ...
I wonder whether perhaps a more basic step is to understand
how type-changing monadic computations can be understood.
By this I mean, that the effects model by the monad can change
their type as part of the computation. Such a monad would be
parameterised by effect types a b, where a is the type of the
effect before computation and b is the type after computation.
The following code illustrates this idea.
Ralf
Warm-up: we compute a normal sequence of monadic ticks,
and we get back the final state and the value of the computation.
ghci6.2> ticks
(3,2)
Demo: we do the same with heterogeneous monadic operations,
and we get back the type-level natural for the final state etc.
ghci6.2> hTicks
(HSucc (HSucc (HSucc HZero)),2)
-}
-----------------------------------------------------------------------------
-- Value-level (i.e., normal) state monads ----------------------------------
-----------------------------------------------------------------------------
-- A silly state monad
data State s a = State (s -> (s,a))
unState (State f) = f
instance Monad (State s)
where
return a = State (\s -> (s,a))
c >>= f = State (\s ->
let (s',a) = unState c s
in unState (f a) s'
)
-- Start with state 0
runZero :: State Int a -> (Int,a)
runZero f = unState f 0
-- Tick and return original value
tick :: State Int Int
tick = State (\s -> (s+1,s))
-- Do a sequence of computations
ticks = runZero ( tick
>>= const tick
>>= const tick)
-----------------------------------------------------------------------------
-- Now in a type-driven fashion ---------------------------------------------
-----------------------------------------------------------------------------
-- A state monad with type-changing states
data HState s s' a = HState (s -> (s',a))
unHState (HState f) = f
-- A class for heterogeneous returns
class HReturn m x
where
hReturn :: a -> m x x a
instance HReturn HState s
where
hReturn a = HState (unState (return a))
-- A class for heterogeneous binds
class HBind m x y z
where
hBind :: m x y a -> (a -> m y z b) -> m x z b
instance HBind HState x y z
where
c `hBind` f = HState (\s ->
let (s',a) = unHState c s
in unHState (f a) s'
)
-- We use type-level naturals for different state types
data HZero = HZero deriving Show
data HSucc x = HSucc x deriving Show
class HNat x
where
hNat :: x -> Int
instance HNat HZero
where
hNat HZero = 0
instance HNat n => HNat (HSucc n)
where
hNat (HSucc n) = 1 + hNat n
-- Start with state HZero
runHZero :: HState HZero n a -> (n,a)
runHZero f = unHState f HZero
-- Tick and return original value
htick :: HNat n => HState n (HSucc n) Int
htick = HState (\s -> (HSucc s,hNat s))
-- Do a sequence of computations
hTicks = runHZero ( htick
`hBind` const htick
`hBind` const htick)
-- Should print: ((3,2),(HSucc (HSucc (HSucc HZero)),2))
main = print (ticks,hTicks)
More information about the Haskell-Cafe
mailing list