instance Monad ST where
--return :: a -> ST a
return x = S (\s -> (x,s))
--(>>=) :: ST a -> (a -> ST b) -> ST b
st >>= f = S (\s -> let (x, s') = app st s
in app (f x) s')
type State = Int
newtype ST a = S (State -> (a, State))
data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Show)
app :: ST a -> State -> (a, State)
app (S st) s = st s
mlabel :: Tree a -> ST (Tree Int)
mlabel (Leaf _) = fresh >>= (\n -> return (Leaf n))
mlabel (Node l r) = mlabel l >>= (\l ->
mlabel r >>= (\r ->
return (Node l r)))
fresh :: ST Int
fresh = S (\n -> (n , n +1))
Hi, so this my code and I want to ensure that my understanding of the expansion of the mlabel function is correct. And I am not using any additional imports.
So suppose mlabel gets a input of Leaf 'a'
fresh >>== (\n -> return (Leaf n))
S (\n -> (n, n+1) >>== (\n -> return (Leaf n))
= S (\s -> let (x, s') = app (S (\n -> (n, n+1)) s
(x, s') = (s, s+1)
in app ((\n -> return (Leaf n) x) s'
= app (S (\x -> (Leaf x, x+1)) s'
= (\x -> (Leaf x, x+1) s'
= (Leaf s+1, (s+1)+1)
You haven't included the definitions of your
>>=andreturnoperations for this monad, but I assume you have something like:If so, there's a problem with your expansion here:
You've got a missing close parenthesis in the first line, and I think you skipped too many steps and got yourself turned around.
Anyway, this should look more like this:
Now, when we substitute in the values of
xands'fromlet (x, s') = (s, s+1) in ..., we get:and not
(Leaf s+1, (s+1)+1).It's probably safer to rewrite the whole
let xxx in yyystatement instead of trying to rewrite thexxxandyyyparts separately, so: