Haskell(>>)运算符

时间:2016-11-25 10:27:18

标签: haskell

runState (modify (+1) >> modify (+1)) 0

有人可以解释上面代码是如何生成的((),2)吗?给定(>>) :: Monad m => m a -> m b -> m b我会认为第一个“修改(+1)”将被删除导致((),1)。

2 个答案:

答案 0 :(得分:6)

>>运算符不是flip const,即使它具有类似的类型签名。如果查看默认实现,可以看到它实际上在第一个参数上调用>>=

a >> b = a >>= \_ -> b

出于这个原因,您可以将>>视为为其“副作用”运行monadic动作,但丢弃结果。如果您将上述>>的定义内联到您的示例中,您得到的结果就会变得非常明确:

runState (modify (+1) >>= \_ -> modify (+1)) 0

这显然会在状态monad的上下文中运行modify (+1)两次,因此结果状态为2,而不是1

答案 1 :(得分:3)

你可以将State s monad视为:

newtype State s a = State { runState :: s -> (a, s) }

让我们看看如何为这个monad实现operator(>>):

(State f) >> (State g) = State (g . snd . f)

如何修改工作:

modify f = State $ \s -> ((), f s)

所以一起撰写:

modify (+1) >> modify (+1) => (State $ \s -> ((), s + 1)) >> ((State $ \s -> ((), s + 1)) => State (\s -> ((), (s + 1) + 1))

然后:

runState (State (\s -> ((), (s + 1) + 1))) 0 => (\s -> ((), (s + 1) + 1)) 0 => ((), (0 + 1) + 1) => ((), 2)