繁体   English   中英

在使用State Monad时了解符号“ <-”吗?

[英]Understanding the symbol “<-” when using State Monad?

Haskell / Understanding monads / State中,有一个代码段代码:

type GeneratorState = State StdGen
rollDie :: GeneratorState Int
rollDie = do generator <- get
         let (value, newGenerator) = randomR (1,6) generator
         put newGenerator
         return value

关于上述第三行中的符号<- ,有一个解释:

我们用<-结合get取出伪随机生成器。 get用状态覆盖单调值( maa ),将生成器绑定到状态。 (如果有疑问,请回顾上面的get和>>=的定义)。

我不明白:(1) generator是否对应于定义State的第一个类型参数? (2)为什么generator只是State的两个参数之一,而不是两个? 当然,从上下文来看,答案是显而易见的,但是我不知道有关<-的具体规则。

据我所知,当评估evalState rollDie (mkStdGen 600)get将被State (mkStdGen 0) (mkStdGen 0)取代,并且根据State (mkStdGen 0) (mkStdGen 0)的描述“ <-将事物从单子中拉出”,这里的事物不是(mkStdGen 0) (mkStdGen 0)

对于您提出的问题,我不太确定,如果我误解了,请纠正我。

do-notation语法<-的语法糖和重载的bind运算符(>>=)之间是等价的。

do { a <- f ; m } ≡ f >>= \a -> do { m }

因此,如果要对装订夹进行脱糖,它将看起来像:

rollDie' :: GeneratorState Int
rollDie' =
  get >>= \generator ->
    let (value, newGenerator) = randomR (1,6) generator in
    put newGenerator >>= \_ ->
      return value

如果您了解State monad的工作原理,则在实现中,它会在每个绑定的隐式参数(即>>= )中围绕状态进行线程化。 简化的实现可能类似于:

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

instance Monad (State s) where
  return a = State $ \s -> (a, s)

  State act >>= k = State $ \s ->
    let (a, s') = act s
    in runState (k a) s'

get :: State s s
get = State $ \s -> (s, s)

put :: s -> State s ()
put s = State $ \_ -> ((), s)

因此,绑定运算符在专门用于此特定State monad时具有以下类型:

(>>=) :: State s a -> (a -> State s b) -> State s b

函数get只是将状态作为参数返回的函数,以便您可以检查它,因此它必须匹配其所驻留的monad的s类型。

--           +--- State
--           | +- Return value (inner state)
--           | |
get :: State s s

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM