然后状态 Monad (>>)
State Monad then (>>)
我想知道 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
这是正确的吗?
我认为 this Wikipedia page 为 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 r
你说的很对。 >>
实际上比你建议的更通用,但你当然可以将它与你指定的类型签名一起使用。如果您使用的是 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 transformer StateT s
,它被用来将状态添加到任意 Monad
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
单独存在,这不是在状态转换器上映射时发生的情况。最终结果:直觉不佳。
我想知道 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
这是正确的吗?
我认为 this Wikipedia page 为 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 r
你说的很对。 >>
实际上比你建议的更通用,但你当然可以将它与你指定的类型签名一起使用。如果您使用的是 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 transformer StateT s
,它被用来将状态添加到任意 Monad
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
单独存在,这不是在状态转换器上映射时发生的情况。最终结果:直觉不佳。