我想在Haskell中构建一个非确定性状态monad。这将允许我使用构建状态生成搜索空间中的所有元素以修剪不良位置。假设我有以下(伪)代码:
primitives :: [State Int Element]
primitives = [... list of primitive stateful elements ...]
combine :: Element -> Element -> State Int Element
expand :: Depth -> [State Int Element]
expand 0 = primitives
expand d = do
... do something to the state ...
left <- expand (d-1)
right <- expand (d-1)
let out = combine left right
guard ( ... some check on out ... )
return out
这里有几件事情是行不通的:我需要了解的最基本的事情是如何做一些陈述,然后将其传递给每个expand
分支。我已尝试使用类型为State Int [ State Int Element]
的函数的一些方法,但最终,一旦我将列表monad的分支包装在状态包装器中,我无法将其删除,对吧?有没有办法做到这一点?
感谢。
答案 0 :(得分:12)
一个简单的State
monad定义为:
data State s a = State (s -> (a, s))
这表示自包含且确定性的有状态计算。将[]
视为非确定性monad,您可以使[State s a]
代表一组非确定性的确定性计算,或State s [a]
代表一个确定性计算,产生一个非确定性集合值。在任何情况下,有状态计算本身的结构都不存在任何非确定性。
要以您想要的方式实际组合状态和非确定性行为,您需要以仅使用{{1}的方式将两者结合起来};这是monad变形金刚的目的。类型State
相当于:
StateT s [] a
这给你的是状态值的非确定性,只有在计算中的任何一点都可以观察到个别选择。
不允许的是分支之间的任何交互;在一个分支中进行的状态更改将永远不会从其他分支中看到,这是非确定性计算中通常所需的。