为什么runState签名只有状态参数? [英] Why runState signature has only state argument?

查看:184
本文介绍了为什么runState签名只有状态参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个真实的例子:如果我心情很好('好状态'),当经理问我估计的时候,我给了他一个确定的答案,但敢于这样做3次<在连续两次没有免费零食的情况下,我的情绪发生了变化(我进入了糟糕的状态),接下来的三次他接近我要求他不要用任何他的废话来打扰我。 / em>



这是我平时的日志:

  [心情:好,耐心:3]  - 上午11:00,我很高兴
ESTIMATE - > bla bla 6,[Mood:Good,Patience:2]
ESTIMATE - > bla bla 1,[心情:好,耐心:1]
Cookies! - > ,[心情:好,耐心:再次3! ]
ESTIMATE - > bla bla 7,[Mood:Good,Patience:2]
ESTIMATE - > bla bla 2,[Mood:Good,Patience:1]
ESTIMATE - > bla bla 9,[心情:坏,耐心:-2] - 够了!
ESTIMATE - > 需要休息一下! [心情:坏,耐心:-1]
估计 - > Deploynig!,[情绪:坏,耐心:0]
估计 - > 午餐时间!,[心情:好,耐心:3] - 好吧,他需要我..
ESTIMATE - > bla bla 6,[Mood:Good,Patience:2]
...

现在,我在工作中的这种模式似乎符合 State Monad。

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

但我该怎么做?这个签名有一个状态的空间,在我的情况下是(Mood,Patience),而不是输入( ESTIMATE Cookies )。这就像我应该回答,甚至没有听!



所以我的问题是:我如何不仅有状态,而且有辩论的计算与 State Haskell monad

解决方案

,一个状态并返回一个输出和一个新状态。所以这个类型将会是 input - >状态 - > (state,output)



runState 只是部分应用的有状态计算已经接受了它的输入。

还要注意,当你编写有状态函数时(即当你使用>> = 绑定运算符或 do 符号),您可以这样做:将输入作为表达式提供,并且绑定仅负责传递状态 em>。



您可以在不使用返回值的情况下调用 get ,但会丢失。如果你想使用它,你必须使用值< - get ,然后提供作为显式输入下一个有状态计算。绑定仅在传递状态时才起作用。






实际示例:考虑函数:

  doStuff :: Int  - > State Int Int 
doStuff x = do
val< - get
put $ val + x + 1
return 0

doStuff 类型正好具有输入 - >状态 - > (状态,输出)。但输入部分由 x 参数表示。
一旦你提供了 x ,你可以得到 state - > (state,output)这正是 runState 所代表的。



实际上不需要有状态动作的参数,因为你可以预先部分地应用它们来获得没有输入的纯态有状态计算(这些是可怕的引号)。

A real-life example: If I'm in a good mood('good state'), when manager asks me about estimates, I give him a solid answer, but dares he to do that 3 times in a row, without some free snacks in between, my mood changes(I get to 'bad state') and the next 3 times he approaches I ask him not to disturb me with any of his nonsense.

Here's a log of my usual day:

                             [ Mood: Good, Patience: 3 ]  -- 11:00 am, I'm happy
ESTIMATE -> "bla bla 6",     [ Mood: Good, Patience: 2 ]
ESTIMATE -> "bla bla 1",     [ Mood: Good, Patience: 1 ]
Cookies! -> "",              [ Mood: Good, Patience: 3 again! ]
ESTIMATE -> "bla bla 7",     [ Mood: Good, Patience: 2 ]
ESTIMATE -> "bla bla 2",     [ Mood: Good, Patience: 1 ]
ESTIMATE -> "bla bla 9",     [ Mood: BAD , Patience: -2 ] -- Enough!
ESTIMATE -> "Need a break!"  [ Mood: BAD , Patience: -1 ]
ESTIMATE -> "Deploynig!",    [ Mood: BAD , Patience: 0 ]
ESTIMATE -> "Lunch time!",   [ Mood: Good, Patience: 3 ]  -- Ok he needs me..
ESTIMATE -> "bla bla 6",     [ Mood: Good, Patience: 2 ]
...

Now this model of me at work seems to fit the State Monad.

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

But how do I do this? The signature has room for a state, which in my case is (Mood,Patience), and not for input (ESTIMATE or Cookies). It's like I'm supposed to answer without even listening!

So my question is: How do I make not only Stateful but also Argumentful computation with State monad of Haskell?

解决方案

A stateful computation gets an input, a state and returns an output and a new state. So the type will be input -> state -> (state, output).

The runState is just a partially applied stateful computation that has already taken its inputs.

Note also that when you compose stateful functions (i.e. when you use the >>= bind operator or do notation) you do exactly this: you supply the inputs as expression and the bind is responsible for passing around only the state.

You can call get without using its return value, but then it gets lost. If you want to make use of it you have to use value <- get and then provide the value as an explicit input for the next stateful computation. The bind only comes into play when passing the state around.


Practical example: consider the function:

doStuff :: Int -> State Int Int
doStuff x = do
    val <- get
    put $ val+x+1
    return 0

The doStuff type has exactly the pattern input -> state -> (state, output). But the input part is represented by the x argument. Once you provide x you get something of type state -> (state, output) which is exactly what runState represents.

So you don't actually need the arguments for stateful actions because you can partially apply them beforehand to obtain "pure stateful computations that have no input" (those are scary quotes).

这篇关于为什么runState签名只有状态参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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