これは、しばしばツリーの縮小と考えられ、分割と征服の削減を実現するため、並列計算では重要です。
最初に、結合機能が非結合である場合、明らかにfoldl
、foldr
、および「非分割の折りたたみ」の間に大きな違いがあります。したがって、結合操作と結合すると仮定しましょう。直ちに、すべての折り目はMonoid
で表すことができます。 foldr
を使用して、デフォルトで定義され、より良いfoldMap :: Monoid m => (a -> m) -> [a] -> m
で表される
foldlm :: Monoid m => [m] -> m
foldlm = foldl mappend mempty
foldrm :: Monoid m => [m] -> m
foldrm = foldr mappend mempty
usfoldm :: Monoid m => [m] -> m
usfoldm = foldTree mappend mempty . buildTree
。
、エレメント
Monoid
Sが結合される方法を制御するツリー状の配列タイプに定義された
Monoid
所与のツリー状unsidedフォールディングを生成するために、最終的な抽出工程を、与えられた場合、十分である
foldMap f = foldr (mappend . f) mempty
。それは根本的なことができますので、
data Tree a
singleton :: a -> Tree a
instance Monoid (Tree a) where ...
foldTree :: Monoid a => Tree a -> a
foldTree . foldMap singleton :: Monoid a => [a] -> a
最後に、我々は我々がfoldr
からfoldMap
を得ることができますが、我々はまた、一般的にfoldMap
newtype Endo a = Endo { appEndo :: a -> a }
instance Monoid (Endo a) where
mempty = id
mappend (Endo f) (Endo g) = Endo (f . g)
foldr f z as = appEndo (foldMap (Endo . f) as) z
からfoldr
を得ることができることを見てきた、foldMap
は、より原始的と考えられていますMonoid
は、好ましい折り畳み方法を選択します。つまり、データ型ごとに効率的または並列のフォールディングを自由に作成することができますが、適切に行うことはまだ難しいでしょう。
foldMap
抽象化は、通常、インスタンスメソッドとしてFoldable
というものがありますが、これは非常に一般的ですが、より新しいHaskellのtypeclassです。 Foldable
が
toList :: Foldable f => f a -> [a]
はまた、私たちは普遍Monoid
あるfoldMap
[a]
としてのMonoid
アル自然を見ることができますされ、存在していることを除いて非常にいくつかの意味の法律を持っているので、またその実用性にもかかわらず、少し愚かであると考えられていた我々 foldr
で回復できます。
融合規則をさらに詳しく調べるには、Gershom BazermanのBuilding up to a Point via Adjunctionsのように、提案されているデュアルタイプクラスBuildable
を読むことが重要です。
そして最後に、人気のように、私は必要があれば、それはより効率的Monoid
折り目が可能になりますが、それはfoldl
、おそらくその相対的な不分明に果たしているfoldr
両方よりも間違いなく新しいだから、それは間違いなく、これらの日Foldable
をインスタンス化する好ましい方法だと思います。
おそらくhttp://cs.stackexchange.comに適しています... –
どうすれば移動できますか? – MaiaVictor
私は答えを投稿しようとしていましたが、私が何を話しているのか全く分からなかったことに気付きました。あなたがそれについて既に認識していないなら、[Foldableクラス](http://hackage.haskell.org/package/base/docs/Data-Foldable.html#t:Foldable)を見てください。これはあなたが記述したような 'fold '演算を定義し、' mappend'の暗黙の 'f'だけで定義します。 – icktoofay