假设以下相互递归结构:
type Tree<'a> =
| Empty
| Node of 'a * 'a Forest
and Forest<'a> =
| Nil
| Cons of 'a Tree * 'a Forest
目标:为此结构生成常见的变态:foldl,foldr,foldk。
我产生了如下的天真变态:
let rec foldTree fEmpty fNode fNil fCons =
function
| Empty -> fEmpty
| Node (a, f) -> fNode a (foldForest fEmpty fNode fNil fCons f)
and foldForest fEmpty fNode fNil fCons =
function
| Nil -> fNil
| Cons (t, f') -> fCons (foldTree fEmpty fNode fNil fCons t) (foldForest fEmpty fNode fNil fCons f')
如何“机械地”生成尾递归 foldl(使用累加器)和尾递归 foldr(使用延续)?
我已经阅读了Scott 的递归类型和折叠系列,并且我了解如何“机械地”为递归结构生成折叠。但是我在谷歌上找不到任何东西来为递归数据结构做“机械”的事情。
PS:可以通过内联来摆脱上面的相互递归,但让我们保留它,因为它代表了tpetricek 的 Markdown 解析器中相互递归的简化版本。