Haskell monad state desugar

时间:2016-06-27 20:50:09

标签: haskell

为了研究州议会的细节,我试图去试图:

我在论坛会员的帮助下粘贴了我能够创建的版本。

我想确保我的思路正确:

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

state :: (s -> (a, s)) -> State s a
 foo = do
      a <-get
      put(a+1)

foo =
  get >>= \a->
  put (a+1)


2. foo= get >>= \a->put(a+1)
   2.1 get = State (\s->(s,s))
   2.2 put a = State(\_->((), a+1)

3. foo= State (\s->(s,s)) >>= \a->State(\_->((), a+1)

4. foo= State (\s0 -> let (a,s1)=runState( State(\s->(s,s)) s0
                               in runState ((\a->State(\_->((),a+1) a) s1

5. foo= State (\s0 -> let (a,s1)=(\s->(s,s)) s0
                               in runState ((\a->State(\_->((),a+1) a) s1

6. foo= State (\s0 -> let (a,s1)=(s0,s0)  -- a=s0 i s1=s0
                               in runState ((\a->State(\_->((),a+1) a) s1

7. foo= State (\s0 ->  runState ((\a->State(\_->((),a+1) s0) s1

8. foo= State (\s0 ->  runState ((State(\_->((),s0+1) ) s1

9.foo= State (\s0 -> ( \_->((),s0+1) 

10.foo= State (\s0 -> ((),s0+1)


11. runState  foo 0

12. runState (State(\s0->((),s0+1) 0

13 . (\s0->((),s0+1) 0

是对的吗? :)

1 个答案:

答案 0 :(得分:1)

我写了一篇博文,几乎就是这个例子:http://www.vaibhavsagar.com/blog/2016/06/17/haskell-state/

如果我们将(>>=)定义为

  (>>=) (State sa) fn =
    State (\s0 -> let (a, s1)  = sa s0
                      State sb = fn a
                  in sb s1)

然后是desugaring

    do i <- get; put (i+1)
 == get >>= \i -> put (i+1)
 == State (\s -> (s, s)) >>= \i -> State (\_ -> ((), i+1))

我们可以通过(>>=)的定义简化:

    (>>=) (State (\s -> (s,s))) (\i -> State (\_ -> ((), i+1))) =
      State (\s0 -> let (a, s1)  = (\s -> (s,s)) s0
                     -- (a, s1)  = (s0, s0)
                        State sb = (\i -> State (\_ -> ((), i+1))) a
                     --       sb = (\_ -> ((), s0+1))
                    in sb s1)
                     -- ((), s0+1)
 == State (\s0 -> ((), s0+1))
 == State (\i  -> ((), i+1))

最后,我们有

    exec (State (\i -> ((), i+1))) 0
 == snd $ runState (State (\i -> ((), i+1))) 0
 == snd $ (\i -> ((), i+1)) 0
 == snd $ ((), 1)
 == 1