Ily*_*gin 7 monads state haskell
一个现实生活中的例子:如果我心情愉快('良好的状态'),当经理问我估计时,我会给他一个坚实的答案,但他敢连续 3次这样做,没有一些免费的中间的小吃,我的情绪发生了变化(我变成了"糟糕的状态"),接下来的3次接近,我请他不要用任何胡言乱语打扰我.
这是我平时的日志:
[ 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 ]
...
Run Code Online (Sandbox Code Playgroud)
现在这个我工作的模型似乎适合StateMonad.
newtype State s a = State { runState :: s -> (a, s) }
Run Code Online (Sandbox Code Playgroud)
但是我该怎么做?签名有一个状态的空间,在我的情况下(Mood,Patience),而不是输入(ESTIMATE或Cookies).这就像我应该在没有听的情况下回答!
所以我的问题是:我如何使用Haskell monad进行有状态计算而且还进行有争议的计算State?
有状态计算获得输入,状态并返回输出和新状态.所以类型将是input -> state -> (state, output).
这runState只是已经采用其输入的部分应用的有状态计算.
还要注意,当你编写有状态函数时(即当你使用>>=绑定操作符或do符号时),你就是这样做的:你将输入作为表达式提供,而bind只负责传递状态.
您可以在get不使用其返回值的情况下调用,但随后会丢失.如果你想使用它,你必须使用value <- get然后提供value作为下一个有状态计算的显式输入.绑定仅在通过状态时发挥作用.
实际例子:考虑功能:
doStuff :: Int -> State Int Int
doStuff x = do
val <- get
put $ val+x+1
return 0
Run Code Online (Sandbox Code Playgroud)
该doStuff类型具有完全相同的模式input -> state -> (state, output).但该input部分由x论证代表.一旦你提供了x你得到的东西,state -> (state, output)这正是runState代表什么.
因此,您实际上并不需要有状态操作的参数,因为您可以事先部分应用它们以获得"没有输入的纯状态计算"(这些是可怕的引用).