我想知道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这是正确的吗?
发布于 2015-12-27 04:10:31
你说得很对。>>实际上比您建议的更通用,但是您当然可以将它与您所指示的类型签名一起使用。如果您使用的是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添加状态的monad转换器StateT s兼容。
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单独使用,所以在状态转换器上映射时不会发生这种情况。最终结果:直觉不佳。
发布于 2015-12-27 04:08:54
我认为这个维基百科页面给出了State monad的(>>=)定义:
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,因此可以将其重写为:
m >> k = \r -> k $ snd m rhttps://stackoverflow.com/questions/34477350
复制相似问题