我正在研究Ocll中类似于haskell的符号的camlp4扩展,并试图找出GHC如何编译递归的do-bindings(使用-XDoRec启用)。
我想知道monadic fixpoint combinator是否有可能以严格的语言存在(如Ocaml / F#/ SML / ...)?
如果是的话,它看起来怎么样?它会非常有用吗?
答案 0 :(得分:14)
F#计算表达式语法(与Haskell do
相关)支持递归:
let rec ones = seq {
yield 1
yield! ones }
这是受支持的,因为除了其他monadic(或 MonadPlus )操作之外,计算构建器还必须支持Delay
操作。代码转换为:
let rec ones =
seq.Combine
( seq.Yield(1),
seq.Delay(fun () -> seq.YieldFrom(ones)) )
Delay
的类型通常是(unit -> M<'T>) -> M<'T>
,其技巧是将带有效果(或直接递归引用)的计算包装到按需评估的延迟计算中。
如果您想进一步了解该机制在F#中的运作方式,那么以下两篇论文是相关的:
第一个描述了如何使用F#计算表达式语法(以及如何插入Delay
- 以及通常,F#如何将延迟和急切计算与效果结合起来),第二个描述F#如何处理{{ 1}}带有值的声明 - 例如上面的let rec
值。