【发布时间】:2019-01-23 06:07:34
【问题描述】:
使用StateT monad 转换器,我可以创建类型StateT s [] a,它与s -> [(a, s)] 同构。现在我更喜欢使用STT monad transformer,因为我想拥有多个不同类型的可变变量,并且希望能够根据早期计算的结果随意实例化它们。
但是,STT 的链接文档明确提到:
这个 monad 转换器不应该与可以包含多个答案的 monad 一起使用,比如 list monad。原因是状态令牌将在不同的答案中重复,这会导致坏事发生(例如失去参考透明度)。安全 monad 包括 monad State、Reader、Writer、Maybe 以及它们对应的 monad 转换器的组合。
那么我有什么选择呢?
完全清楚:
- 我所追求的是非确定性。我希望能够分叉我的计算,为每个分支提供自己的整个状态的副本。
- 我不太介意并行性,因为性能不是我最关心的问题。
- 我不关注的是并发:不同的计算分支不应共享可变变量;相反,他们都应该使用自己的原始可变变量副本。
编辑:
(编辑编辑:以下反例无效,因为 ListT 不应应用于非交换单子 ST 和 State。)
我开始意识到 STT monad 转换器的行为与 StateT 一样,本质上是不安全的。有了它,我们可以构建一个类型STT sloc (ListT (ST sglob)) a。这里,sglob 是全局状态的名称,而sloc 是本地状态的名称。*
现在我们可以使用全局状态在线程之间交换局部状态引用,从而有可能获得对未初始化变量的引用。
*为了比较,对应的StateT构造为StateT sloc (ListT (State sglob)) a,与sloc -> sglob -> ([(a, sloc)], sglob)同构。
【问题讨论】:
标签: haskell state-monad non-deterministic st-monad