5

私はFoldableHaskellのクラスを見ています。メソッドのうちの 2 つは、Monoid インスタンスを必要としますfoldfoldMapしかし、foldrまたはfoldlそのような制約はありません。

fold :: Monoid m => t m -> m
foldMap :: Monoid m => (a -> m) -> t a -> m
foldr :: (a -> b -> b) -> b -> t a -> b
foldl :: (b -> a -> b) -> b -> t a -> b

foldr/の結果foldlが同等であるためには、指定された折り畳み関数を連想的に制限するべきではありませんか? 同じリストで、foldr/foldl の結果が異なる例はありますか?

Foldable インスタンスは Monoidal 値をラップすべきではありませんか? それともFoldableの方が一般的ですか?

4

1 に答える 1

5

foldr/の結果foldlが同等であるためには、指定された折り畳み関数を連想的に制限するべきではありませんか? foldr/の結果がfoldl同じリストで異なる例はありますか?

はい。非連想関数 (減算など(-)) を渡すと、まったく異なる結果が得られます。そして、あなたが正しく指摘して いるように、 のMonoidようなものに対応するインスタンスはありません(-)

しかし、それは設計によるものです。連想関数を使用する必要がFoldableあるインスタンスには、そのような制限はfoldrありません。foldl減算などでフォールドしたい場合があります。のインスタンスは、 ができることFoldable fを制限することに関心fがあります。特に法律は次のとおりです。

foldr f z t = appEndo (foldMap (Endo . f) t ) z
foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z
fold = foldMap id

-- if f is a Functor
foldMap f = fold . fmap f
foldMap f . fmap g = foldMap (f . g)

ソースを見ると、foldrデフォルトでnewtype Endo a = Endo (a -> a)準同型モノイドを巧妙に使っていることがわかります。

-- | Right-associative fold of a structure.
--
-- @'foldr' f z = 'Prelude.foldr' f z . 'toList'@
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z

おそらく非モノイドのfとからモノイドの折り畳みを構築しzます。

最終的には、「モノイドが要件ではないのはなぜですか?」という質問に対する答えです。「それはより実用的であり、最終的には必要ないからです」というのは非常に退屈です。

詳細については、すべての始まりとなった論文Applicative Programming with Effectsを参照してください。

于 2016-06-22T16:58:31.947 に答える