【发布时间】:2015-07-19 23:01:52
【问题描述】:
此代码来自article
在这部分之前我一直能够关注它。
module Test where
type State = Int
data ST a = S (State -> (a, State))
apply :: ST a -> State -> (a,State)
apply (S f) x = f x
fresh = S (\n -> (n, n+1))
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') = apply st s in apply (f x) s')
data Tree a = Leaf a | Node (Tree a) (Tree a) deriving (Show)
mlabel :: Tree a -> ST (Tree (a,Int))
-- THIS IS THE PART I DON'T UNDERSTAND:
mlabel (Leaf x) = do n <- fresh
return (Leaf (x,n))
mlabel (Node l r) = do l' <- mlabel l
r' <- mlabel r
return (Node l' r')
label t = fst (apply (mlabel t) 0)
tree = Node (Node (Leaf 'a') (Leaf 'b')) (Leaf 'c')
而label tree 产生:
Node (Node (Leaf ('a',0)) (Leaf ('b',1))) (Leaf ('c',2))
我可以看到 >>= 运算符是“链接”返回 monad(或类似的东西)的函数的工具。
虽然我认为我理解这段代码,但我不明白这段特定代码的工作原理。
特别是do n <- fresh。我们还没有向fresh传递任何论据,对吧?在这种情况下,n <- fresh 会产生什么?完全不明白这一点。也许它与咖喱有关?
【问题讨论】:
标签: haskell monads state-monad