hdb*_*db3 3 arrays haskell mutable state-monad monad-transformers
我正在构建代码以获得理解,实际上是Solitaire求解器.我有一个简单的暴力实现,它使用状态monad,实际上只是为了证明我可以使用它(它只保留每个移动的计数).但是现在我想使用Unboxed Mutable数组来记录被访问的板,从而在我到达已经通过另一条路径访问的板位置时快速评估路径.似乎ST monad不允许我线程隐式状态,但是我必须使用ST(或IO)才能访问Mutable数组.因此,似乎我必须结合两个Monads - State来线程化状态(实际上包括一个Mutable数组),另一个(ST)来获得Mutable数组函数.
我不是百分之百确定ST monad是改善像这样的搜索任务的性能的方法.但假设它是......你可以通过将你想要保留的状态放入一个"线程状态" STRef.你可以做到这一点,而不需要将多个monad混合在一起,这会让事情变得更加简单.
如果你想要可变状态,你肯定需要ST或IO monad.(或STM monad,但这只用于线程同步,这里你不需要.)
在单子堆叠顺序可以重要-但在这种情况下,它没有.如果你有这样的事情的清单单子和错误单子,然后根据不同的堆叠顺序上的错误或者失败,这个名单仅仅是一种可能性,或者所有列表中的可能性.对于您的情况,没有任何效果会根据堆栈顺序而改变.
...幸运的是,因为没有用于将物品转换成ST的变压器.ST 必须是内在的monad.
说了这么多,我认为你真的不需要monad堆栈.我认为一个简单的STRef意志.
使用时ST,任何数组或引用您有没有真正说明在State这个词的单子感:他们决不会被修改!你可以把它们想象成一个指针;指针是常量,虽然它指向的东西可能会改变。因此,您可以将数组或引用或任何内容ST作为函数参数传递给您的操作。StateT如果您希望ST操作需要返回与传递的数组不同的数组,则该机制将是合适的——即不仅修改现有数组,而且创建一个新数组。由于一般情况并非如此,StateT是不合适的。
如果你真的想要一个 monad 转换器堆栈,你可以把你的数组和引用放到一个ReaderTmonad的环境中。但这可能不是必需的。