foldr
は、自転車のような奇妙なツールの1つです。一度使用すると使いやすいものですが、最初から学ぶのは難しいです。数年の経験を経て、私はfoldr
で解決できる問題を見つけ、すぐに正しく解決することができました。しかし、私が十分にやったこと説明する詳細!
実際には、私は通常、曖昧に連続通しの言語でfoldr
と考えています。 foldr
だけ三つの引数に適用される「シンプル」の場合を無視すると、foldr
の適用は、次のようになります。
foldr go finish xs acc1 acc2 ... where
finish acc1 acc2 ... = ?
go x cont acc1 acc2 ... = ?
acc1
など、アキュムレータは、「左から右へ」渡されます。結果は、概念的には、「右から左に」渡された単一の値から成ります。
finish
は、アキュムレータの最終値を取得し、結果の種類を生成します。あなたがあなたの折り目を生成したいだけで何把握たら
foldr go finish [] acc1 acc2 ...
=
finish acc1 acc2 ...
だから、finish
を書くことが、かなりの機械であるため、これは通常の書き込みするための最も簡単な部分です。
go
は、単一のコンテナ要素、「継続」、およびアキュムレータを取得します。それらのアキュムレータが結果を得るために継続に「転送」し、その結果を使用して独自のものを構築する場合は、変更された値を渡します。
foldl
は、新しいアキュムレータ引数を使用してコンテナの残りの部分を折りたたんで結果を返すため、特に単純なケースです。私はもう少し実例を見るのが少し面白いと思います。ここでは数値のコンテナを取り、実行中の合計と実行中の製品を表すペアのリストを生成します。
sumsProducts :: (Num n, Foldable f) => f n -> [(n, n)]
sumsProducts xs = foldr go finish xs 0 1
where
finish total prod = [(total, prod)]
go x cont total prod =
(total, prod) : cont (x + total) (x * prod)
1:あなた 'G'関数のパラメータ、2'のconst X = \ yを - > X ' – Carsten