haskell Monad: Status Monad

来源:互联网 发布:ecs windows svn搭建 编辑:程序博客网 时间:2024/05/16 15:15

接受一个状态,回传一个值跟一个新的状态。写起来会像这样:(s 是状态的型态,而 a 是计算结果的型态。)

-> (a,s)

堆栈: 堆栈的数据为状态

type Stack = [Int]   
  
pop :: Stack -> (Int,Stack)   
pop (x:xs) = (x,xs)   
push :: Int -> Stack -> ((),Stack)   
push a xs = ((),a:xs)
Control.Monad.State 这个模块提供了一个 newtype 包起来的型态。

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

instance Monad (State s) where   
    return x = State $ \s -> (x,s)   
    (State h) >>= f = State $ \s -> let (a, newState) = h s   
                                        (State g) = f a   
                                    in  g newState
f :  (a -> m b) 类型的, (State g) = f a 是可以理解

(State h) 应该是个 m a 类型。 就这样意会下: 

   1. 被容器包含的Content 取值需要, 只要把 Content 去掉。 Just 1 -----> 1

   2. 函数 s -> (a, s) 取值, 就喂他一个参数。 

   3. (State h) 为什么是一个实例? 出现在原型行的是类型说明 (::), 出现在实现行的是 构造子 (=).  出现在 实现(>>= 的实现), 那么 State 是 构造子, 他的参数h 应该是 s->(a,s) 的一个函数。 随便一说: 上面的 State s 是类型说明, Monad 类型需要一个参数的构造子, 所以 State 两个参数, 需要绑定一个参数s, 整体作为Monad 的一个类型。

   4. 去掉 State 的包装, 发现和Reader Monad 好像


import Control.Monad.State   
   
pop :: State Stack Int   
pop = State $ \(x:xs) -> (x,xs)   
 
push :: Int -> State Stack ()   
push a = State $ \xs -> ((),a:xs)
pop, push a 就都变成了 State. (转换器)  s 是Stack

import Control.Monad.State   
   
stackManip :: State Stack Int   
stackManip = do   
  push 3   
  a <- pop   
  pop
do 的结果会是一个 monadic value。 


我们可以看看对于 State 而言,>>= 的型态会是什么:( m  =  State s 就这么记)

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