哈斯克尔州立莫纳德 [英] Haskell State Monad

查看:89
本文介绍了哈斯克尔州立莫纳德的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

状态Monad的put函数是否更新实际状态,还是仅返回具有新值的新状态?我的问题是,在命令式设置中,可以将State Monad用作全局变量"吗? put会修改全局变量"吗?

Does the put function of the State Monad update the actual state or does it just return a new state with the new value? My question is, can the State Monad be used like a "global variable" in an imperative setting? And does put modify the "global variable"?

我的理解是不,它不会修改初始状态,但是使用monadic接口,我们可以传递新的状态b/w计算,而使初始状态保持完整".这样对吗?如果没有,请纠正我.

My understanding was NO it does NOT modify the initial state, but using the monadic interface we can just pass around the new states b/w computations, leaving the initial state "intact". Is this correct? if not, please correct me.

推荐答案

答案在类型中.

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

因此,状态本质上是一个函数,它带有一个参数"s"(我们称为状态),并返回一个元组(值,状态). monad的实现方式如下

Thus, a state is essentially a function that takes one parameter, 's' (which we call the state), and returns a tuple (value, state). The monad is implemented like below

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

因此,您有一个在初始状态下运行的函数,并吐出一个值状态元组,以供合成中的下一个函数处理.

Thus, you have a function that operates on the initial state and spits out a value-state tuple to be processed by the next function in the composition.

现在,put是以下功能.

put newState = State $ \s -> ((),newState)

这实际上设置了将要传递给合成中下一个函数的状态,而下游函数将看到修改后的状态.

This essentially sets the state that will be passed to the next function in the composition and the downstream function will see the modified state.

实际上,State monad是完全纯净的(也就是说,没有设置任何东西);只有传递给下游的内容会发生变化.换句话说,State monad省去了用Haskell这样的纯语言显式地建立州的麻烦.换句话说,State monad仅提供一个隐藏状态线程详细信息的接口(我认为这是WikiBooks中的内容,或者我认为是Haskell的意思).

In fact, the State monad is completely pure (that is, nothing is being set); only what is passed downstream changes. In other words, the State monad saves you the trouble of carrying around a state explicitly in a pure language like Haskell. In other words, State monad just provides an interface that hides the details of state threading (that's what is called in the WikiBooks and or Learn you a Haskell, I think).

以下内容显示了这一点.您已经得到了get,它将值字段设置为与状态字段相同(请注意,当我指的是设置时,我指的是输出,而不是变量). put通过传递给它的值获取状态,对其进行递增,并使用该新值设置状态.

The following shows this in action. You have get, which sets the value field to be the same as the state field (Note that, when I mean setting, I mean the output, not a variable). put gets the state via the value passed to it, increments it and sets the state with this new value.

-- execState :: State s a -> s -> s
let x =  get >>= \x -> put (x+10)
execState x 10

以上输出20.

现在,让我们执行以下操作.

Now, let's do the following.

execState (x >> x) 10

这将给出30的输出.第一个x通过put将状态设置为20.现在,第二个x使用它. get此时将传递给它的状态设置为value字段,现在为20.现在,我们的看跌期权将获得该值,将其递增10,并将其设置为新状态.

This will give an output of 30. The first x sets the state to 20 via the put. This is now used by the second x. The get at this point sets the state passed it to the value field, which is now 20. Now, our put will get this value, increment it by 10 and set this as the new state.

因此,您在纯上下文中具有状态.希望这会有所帮助.

Thus, you have states in a pure context. Hope this helps.

这篇关于哈斯克尔州立莫纳德的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆