了解State Monad中的State论点

时间:2019-05-20 13:17:16

标签: haskell monads state-monad

我非常努力地将头缠绕在Monad州周围,我不理解以下内容:

考虑到return(>>=)的实现,当您说State $ \s ->....时,s来自哪里?我的意思是,当您开始执行>>= ... >>=时,这是否意味着您需要在链的开始位置以某种方式提供该初始参数?

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

 instance Monad (State s) where
        return a=State $ \s->(a,s)
        (>>=) m g=State $ \s -> let (a,s')= runState m s in
                                   runState (g a) s'

(>>=)中,您说的是State $ \s -> runState m s,当 是最初的(\s -> ...) argument(带有 REAL { {1}})叫?

请问有人可以解释吗?

稍后编辑

有人可以告诉我如何设置argument状态,比如说是否需要使用initial获取值吗?

getLine

3 个答案:

答案 0 :(得分:5)

  

当您说State $ \s ->....时,s来自哪里?

它是 will 来自调用,当runState 将初始状态值提供给state-monadic值时,将运行它描述的组合计算:

st = do { x <- get ; return (x+1) }

x = runState st 0    -- x is (1,0)

我还感觉到您还有另一个可能的误解:您写道:“ 何时被称为初始(\s -> ...) argument?”没有“初始” lambda:lambda全部嵌套在里面!

do { a <- as; b <- bs; c <- foo b; return c }

翻译为

as >>= (\a -> bs >>= (\b -> foo b >>= (\c -> return c)))

所以它不是“ initial”,而是一个以初始状态调用的全封闭lambda组合!

然后将呼叫

let (a,s1) = runState as s0

等在as块中带有该“初始” do

答案 1 :(得分:2)

do块不执行任何有状态计算-它仅将一些较小的有状态计算组合为一个较大的有状态计算。在do级别上,实际状态不存在。

如果将monad称为“有状态计算”,它将更加简单,甚至可能更加准确。或“一个具有类型S状态并返回其实际结果的另一个状态的函数”。然后,您可以想象>>=为“将上述类型的两个函数合并为一个,从而将第一个函数返回的状态作为参数传递给第二个函数”。

答案 2 :(得分:1)

State只是类型s -> (a, s)的函数的包装。 runState实际上并没有“运行”任何东西。它只返回由State构造函数包装的函数。但是,您可以将runState($)运算符进行函数比较。

($)             f  x = f x
runState (State f) s = f s

这使得(=<<) = flip (>>=)(<<<) = (.)类似;与其采用两个函数并返回第三个函数,不如采用一个函数(返回一个State)和一个State并生成第二个State

不过,我们将直接比较(>>=)(>>>) = flip (.),以使类型更好地对齐。 (类似地,您可以将(.)(=<<)进行比较。)

-- f :: t -> a
-- g ::      a -> b
f >>> g =         \t -> let a       = ($)      f     t
                        in            ($)      g     a
-- m :: State s a
-- g ::         a -> State s b
m >>= g = State $ \s -> let (a, s') = runState m     s
                        in            runState (g a) s'