如何在 OCaml 中实施运算符
mfix : ('a -> 'a state_monad) -> 'a state_monad
状态monad? (因为它很大程度上依赖于懒惰,我想必须使用标准库中的Lazy模块。)
更确切地说:
假设带有
的签名type 'a t
( >>= ) : 'a t -> ('a -> 'b t) -> 'b t
mfix
是等式中最不固定的点:mfix f = mfix f >>= f
但是如果你把它简单地定义为
let rec mfix f = mfix f >>= f
由于OCaml的严格语义而不是Haskell的惰性语义,最终导致循环递归。
以实例
为例type 'a t = 'a list
let ( >>= ) m f = List.flatten (List.map f m)
然后例如
let _ = mfix (fun _ -> [])
导致堆栈溢出,而我希望它是[]
。
我想有一种方法可以使用标准库的Lazy模块来解决这个问题,但我找不到。