State Monad然后(>>)

时间:2015-12-27 03:31:53

标签: haskell state-monad

我想知道Haskell状态monad的>>的定义。

根据我的猜测,它将一个州传递给另一个州:

(>>) :: State s a -> State s b -> State s b
State a >> State b = State $ \x -> b $ snd ( a x )

State a >> State b = State $ b . snd . a

这是对的吗?

2 个答案:

答案 0 :(得分:4)

你说得对。 >>实际上比您建议的更为通用,但您当然可以将其与您指明的类型签名一起使用。如果您使用State来自其通常的家Control.Monad.Trans.State.Strict或其家外之家Control.Monad.State.Strict,则State实际上只是一种类型同义词:

type State s = StateT s Identity

其中Identity来自Data.Functor.Identity并已定义

newtype Identity x = Identity x

StateT已定义

newtype StateT s m a = StateT {runStateT :: s -> m (a, s)}

所以State s a只是

的新类型包装器
s -> Identity (a, s)

这与您想象的定义基本相同,但它允许State s monad转换器 StateT s兼容,后者用于向任意添加状态Monad秒。

instance Monad m => Monad (StateT s m) where
  return a = StateT $ \s -> return (a, s)
  StateT g >>= f = StateT $ \s -> g s >>= \(r,s') -> runStateT (f r) s'

所以

  StateT g >> StateT h = StateT $ \s -> g s >>= \(_,s') -> h s'

                       = StateT $ \s -> h $ snd $ runIdentity (g s)
                       = StateT $ h . snd . runIdentity . g

不相关的附注

StateT的定义让我很恼火,因为在我看来,这些对的元素排列错误。为什么错?因为(a, s)上的映射会更改s而只留下a,而这不是映射状态转换器时发生的情况。最终结果:直觉不佳。

答案 1 :(得分:2)

我认为this Wikipedia page(>>=) monad提供了State的定义:

m >>= f = \r -> let (x, s) = m r in (f x) s

由于(>>)(>>=)实施,如下所示:

m >> k = m >>= \_ -> k

可以为状态monad导出(>>)的定义:

m >> k = \r -> let (x, s) = m r in ((\_ -> k) x) s

或消除噪音时:

m >> k = \r -> let (x, s) = m r in k s

既然x没有参与in子句,您确实可以使用snd来获取s,因此可以将其重写为:{/ p>

m >> k = \r -> k $ snd m r