我错过了关于State Monad的一些基本信息吗?为什么要分别保持状态和输入?

时间:2014-02-26 06:44:10

标签: haskell state-monad

为什么我们的函数需要采用状态和输入而不仅仅是包含输入的状态(或包含状态的输入?)。

我假设你可能想要使用相同的状态应用不同的输入,因此你想分开保存它们,但这是唯一的原因吗?

感觉我错过了一些基本的东西,但我无法理解。

4 个答案:

答案 0 :(得分:1)

这是因为方便。一般来说,单独的参数,如果它们在概念上分开(例如,它们不是单个对象的属性,例如),则优于打包在数据类型中,因为在前一种情况下,可以使用currying,combinators等功能方法的优点。

如果没有monad,每个有状态函数看起来都像foo :: b -> s -> (s, a),对于monad,我们可以提取公共部分,命名为:newtype State s a = State (s -> (s, a)),并定义return和{{1} } 为了它。此外,任何简单的函数>>=都可以通过简单的结果更改轻松转换为有状态:bar :: a -> b。如果输入和状态都在一个参数中进行(例如,元组:bar :: a -> State s b,那就不可能。

答案 1 :(得分:1)

我不完全确定你的实际问题是什么,但这里有一些事实可能会回答:

  1. 状态数据是可变的(通过State monad),输入数据是不可变的。在Haskell中,通常可以实现最大的类型级安全性。如果你将输入与状态联合起来,那么你也可以将它变为可变的。

  2. Monads没有输入。您可能会考虑arrows。实际上有a state arrow

答案 2 :(得分:0)

状态monad很有用,因为它强制执行从类型中显而易见的模式。

而不是让代码中的每个函数看起来像:

foo state x y = ... return (state', z)

您可以使用State来明确您的意图。

答案 3 :(得分:0)

术语:如果你是Haskell的新手,很容易被“状态数据可变”等语句搞糊涂/欺骗。来自命令式程序的人可能会采用“可变”来表示更改现有位置的值。对于Haskell的某些部分(例如,IORef)确实如此。在State monad案例中,事实并非如此。

State支持将状态变为新状态 - 新状态完全独立于旧状态。没有任何东西发生变异。

有时这被称为“有效”编程 - 你可以获得效果的好处,但不使用“真正的”副作用 - State是完全纯粹的。