简短的回答:
State旨在利用 monad 的特性来模拟带有局部变量的命令式系统状态。基本思想是在 monad 中隐藏获取当前状态并在每一步返回新状态以及中间结果的活动(这里我们有s -> (a,s).
- 不要将任意函数与包含在
State. 前者可能有你想要的任何类型(前提是State a如果你想在 state monad 中使用它们,它们最终会产生一些)。后者拥有 type 的函数s -> (a,s):这是由 monad 管理的状态传递层。
- 正如我所说,包含在其中的函数
State实际上是通过为实例定义的(>>=)并return通过它们生成的。Monad (State s)它的作用是通过代码调用传递状态。
第 3 点也是 state 参数从 state monad 中实际使用的函数中消失的原因。
长答案:
State Monad 已经在不同的论文中进行了研究,并且也存在于 Haskell 框架中(我现在不记得好的参考资料,我会尽快添加它们)。
这就是它遵循的想法:考虑一个data MyState = ...其值保持系统当前状态的类型。
如果你想通过一堆函数传递它,你应该以这样的方式编写每个函数,它至少将当前状态作为参数并返回一对及其结果(取决于状态和其他输入参数)和新的(可能修改的)状态。嗯,这正是 state monad 的类型告诉你的s -> (a, s):在我们的示例中,sisMyState并且旨在传递系统的状态。
包裹在 中的函数State不接受参数,除了来自当前状态,这是生成新状态和中间结果所必需的。您在示例中看到的具有更多参数的函数不是问题,因为当您do在 monad 中的 -notation 中使用它们时,您会将它们应用于所有“额外”需要的参数,这意味着它们中的每一个都会产生在一个部分应用的函数中,其唯一的剩余参数是状态;monad 实例State将完成其余的工作。
如果您查看可能在 monad 中使用的函数的类型(实际上,在 monad 中它们通常称为操作),您会看到它们的结果类型被装箱在 monad 中:这就是告诉您的点一旦你给了它们所有的参数,它们实际上不会返回结果,而是(在这种情况下)一个s -> (a,s)符合 monad 组合法则的函数。
计算将通过将系统的第一/初始状态传递给整个块/组合来执行。
最后,不带参数的函数将具有类似State awherea的返回类型的类型:如果您查看 的值构造函数State,您会再次看到这实际上是一个函数s -> (a,s)。