アイデアは、Haskell の代数データ型の値は次の形式を持つということです。
C x_1 x_2 ... x_n
ここでC
はコンストラクターで、x_i
は引数です。何
gfoldl app con
そのような値を
con C `app` x_1 `app` x_2 ... `app` x_n
それによって を に変えa
ますc a
。の型C
が
C :: T_1 -> T_2 -> ... -> T_n -> D
次に、中間式の型を見てみましょう。
con C :: c (T_1 -> T_2 -> ... -> T_n -> D)
con C `app` x_1 :: c (T_2 -> ... -> T_n -> D)
con C `app` x_1 `app` x_2 :: c (... -> T_n -> D)
con C `app` x_1 `app` x_2 ... `app` x_n :: c D
パラメータ化c
により、これらすべての中間型を異なるものにすることができます。代わりにのような単純な折り畳みを使用する場合、gfoldl'
これらの中間型はすべて同じでなければなりません。
の動機は、SYB 関数と(およびその他のいくつか)gfoldl
を表現できる単一の一般化になることです。とのタイプは次のとおりです。gmapQ
gmapT
gmapQ
gmapT
gmapQ :: Data a => (forall d. Data d => d -> u) -> a -> [u]
gmapT :: Data a => (forall b. Data b => b -> b) -> a -> a
はをのgmapQ
均一a
なリストにまとめ、u
を使用して表現できますがgfoldl'
、これは では不可能ですgmapT
。
ただし、 を使用するとgfoldl
、 を使用c = Identity
して のようなものを取得したりgmapT
、 のようなc = Const
ものを取得したりできますgmapQ
。
詳細については、その論文で呼び出されているデータ型の通常の (さらに高次の) フォールドであることを示す論文Scrap yourボイラープレート Reloadedも参照してください。gfoldl
Spine
恒等ファンクターと定数ファンクターを使用して、単一の基になる表現から変換動作と更新動作の両方を取得する方法は、「van Laarhoven」レンズからレンズ操作を取得する方法と類似しています。