15

Dataコア関数の 1 つとして定義されますgfoldl

gfoldl
  :: (Data a)
  => (forall d b. Data d => c (d -> b) -> d -> c b) 
  -> (forall g. g -> c g)   
  -> a  
  -> c a

cその目的は何c (d -> b)ですか?通常の折り方ではないのはなぜですか

gfoldl'
  :: (Data a)
  => (forall d. Data d => r -> d -> r)
  -> r
  -> a  
  -> r
4

1 に答える 1

15

アイデアは、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を表現できる単一の一般化になることです。とのタイプは次のとおりです。gmapQgmapTgmapQgmapT

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も参照してください。gfoldlSpine

恒等ファンクターと定数ファンクターを使用して、単一の基になる表現から変換動作と更新動作の両方を取得する方法は、「van Laarhoven」レンズからレンズ操作を取得する方法と類似しています。

于 2015-03-18T12:00:46.453 に答える