Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 理解国家元_Haskell_Monads_State Monad - Fatal编程技术网

Haskell 理解国家元

Haskell 理解国家元,haskell,monads,state-monad,Haskell,Monads,State Monad,我是一个haskell初学者,试图理解StateMonad的这个定义,特别是bind操作。它摘自第4页 首先,您需要了解>>=的类型;我想你会的,因为它在那篇论文的第二页,你已经通过了 如果我们定义runState,bind的定义可能更容易理解 newtype SM s a = SM (s -> (a, s)) runState :: SM a -> s -> (a, s) runState (SM f) s = f s -- this is equival

我是一个haskell初学者,试图理解StateMonad的这个定义,特别是bind操作。它摘自第4页


首先,您需要了解
>>=
的类型;我想你会的,因为它在那篇论文的第二页,你已经通过了

如果我们定义
runState
,bind的定义可能更容易理解

newtype SM s a = SM (s -> (a, s))

runState ::  SM a  -> s -> (a, s)
runState    (SM f)    s =  f s
-- this is equivalent to
-- runState (SM f) =  f
runState
通过提取转换状态的函数
f
并将其应用于初始状态
s
来运行状态monad。函数
f
返回类型为
(a,s)
的元组。元组包含依赖于状态的值(类型
a
)和新状态(类型
s
)。以下是等效的

let (a, s') = runState x s
in ...

let SM x' = x
    (a, s') = x' s
in ...
这两个函数都提取函数
x'
,了解状态如何从
x
转换,然后将其应用于初始状态
s
。结果元组
(a,s')
包含依赖于状态的值
a
,以及新状态
s'

我们可以用
runState
替换
>=
定义中的
SM
模式匹配

 x >>= f = SM (\s -> let
                         (a, s')  = runState x     s
                         (b, s'') = runState (f a) s'
                     in  (b, s''))
现在我们要一件一件地看一遍

Bind构造一个新的
StateMonad
,该函数依赖于一些初始状态
s
。它返回一个状态相关值
b
和一个新状态
s'

通过使用初始状态
s
运行状态monad
x
计算状态相关值
a
和新状态
s'

 x >>= f = SM (\s -> let
                         ...
                     in  (b, s''))
                     let
                         (a, s')  = runState x     s
根据用户提供的函数
f
和依赖于状态的值
A
确定新的状态monad
f A
。第二个状态monad使用中间状态
s'
运行。它计算另一个状态相关值
b
和最终状态
s'


第二个依赖于状态的值
b
和最终状态
s'
是为新的
StateMonad
构造的函数返回的,这是对
Cirdec
的一个略短的补充答案

首先,回想一下在
x>=f
中,
x
是状态单子,
f
是返回状态单子的fn,
x>=f
也是状态单子

基本思路如下。给定一些当前状态
s
(稍后当我们运行由
x>=f
表示的状态monad时将提供),我们首先希望使用
s
运行
x
,这将产生一些值
a
,以及一个新状态
s'
。然后我们想运行fa,这给了我们另一个状态monad。但是,我们不只是想在任何状态下运行这个结果状态monad
fa
;相反,我们希望用
x
产生的状态运行它,即
s'
,给我们一些新值
b
和一些新状态
s'
x>>=f
将表示从
s->(b,s')
进行的计算

请记住:使用状态单子的全部目的是避免将状态作为另一个参数显式传递给所有函数(这将非常混乱,非常快)。因此,这里的想法是,每当我们将动作绑定到状态monad时,都要在后台正确地执行状态线程


为此,我们(1)在
x
上进行模式匹配以获取内部fn,然后(2)使用当前状态
s
运行此函数以获得结果
a
和一些新状态
s'
。然后我们(3)计算fa,它返回一个状态monad,并在这个monad上进行模式匹配以得到内部的fn;然后(4)使用状态
s'
运行fn,以获得值
b
和一些最终状态
s'
。(1) 到(4)对应于紧跟在
后面的四行,让
插入代码。你知道什么,我们刚刚定义了一个fn,从
s
(b,s“”)
,它在幕后正确地传递状态。现在我们将把它包装在一个构造函数中,我们就完成了
x>>=f
现在表示我们可以稍后通过提供初始状态来运行的计算

你的抄本缺少一个非常重要的部分。
let
的第二行应该是
SM(a,s')=x's
                     let
                         (a, s')  = runState x     s
                         (b, s'') = runState (f a) s'