次の相互再帰構造を想定します。
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 の Recursive Types and Folds シリーズを読んでいて、再帰構造の折り畳みを「機械的に」生成する方法を理解しています。ただし、再帰的なデータ構造に対して「機械的な」ことを行うためにグーグルで何かを見つけることができません。
PS: インライン化することで上記の相互再帰を取り除くことができますが、tpetricek の Markdown パーサーでの相互再帰の単純化されたバージョンを表すため、そのままにしておきます。