Foldable
は非常に混乱しやすいクラスです。正直なところ、多くの法律がないため、ほぼすべての種類の異なるFoldable
インスタンスをかなり書くことが可能です。幸いなことに、同じタイプのがある場合はTraversable
インスタンスに基づいて、Foldable
インスタンスが純粋に機械的な方法で何をすべきかを理解することができます。私たちは、
class (Functor t, Foldable t) => Traversable t where
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
Traversable
を持って
は、いくつかの異なる法律がありますが、それは最も重要なものはtraverse Identity = Identity
で判明します。のは、これがMaybe
に適用される方法を見てみましょう:
traverse :: Applicative f => (a -> f b) -> Maybe a -> f (Maybe b)
traverse g Nothing = _none
traverse g (Just a) = _some
は今最初のケースでは、あなたはf (Maybe b)
を生成する必要がある、とあなたが持っているすべてがg :: a -> f b
です。 f
の値がなく、a
の値がないため、生成できるのはpure Nothing
です。
2番目のケースでは、f (Maybe b)
を生成し、g :: a -> f b
とa
が必要です。だから興味深いのは、g
をa
に適用してg a :: f b
にすることです。これで、この値を捨ててNothing
を返すか、Just
にまとめて返すことができます。
同一性法により、traverse Identity (Just a) = Identity (Just a)
。あなたはNothing
を返すことができません。 のみ法的定義はMaybe
ためTraversable
インスタンスが完全にTraversable
法律やparametricityによって決定され
traverse _ Nothing = pure Nothing
traverse g (Just a) = Just <$> g a
です。これはMaybe
に適用されるとして、
foldMapDefault :: (Traversable t, Monoid m)
=> (a -> m) -> t a -> m
foldMapDefault f xs =
getConst (traverse (Const . f) xs)
私たちの定義を拡大
foldMapDefault f Nothing =
getConst (traverse (Const . f) Nothing)
foldMapDefault f (Just a) =
getConst (traverse (Const . f) (Just a))
、pure
と<$>
の定義によって
foldMapDefault f Nothing = getConst (pure Nothing)
foldMapDefault f (Just a) = getConst (Just <$> (Const (f a)))
:
今ではtraverse
を使用して折り畳むことが可能です0の場合は、これらのコンストラクタをアンラップ
foldMapDefault f Nothing = getConst (Const mempty)
foldMapDefault f (Just a) = getConst (Const (f a))
、
foldMapDefault f Nothing = mempty
foldMapDefault f (Just a) = f a
されており、これはfoldMap
がMaybe
に定義されている正確にどのように確かにあります。
ヒント:ある意味では、「たぶん」は0または1の要素のリストと考えることができ、それらのそれぞれについて「fold」*が明確に定義されています。 –
これをより明示的にするために、Foldableをリストに変換することができることに注意してください。 'toList <$> [Nothing、Just True] == [[]、[True]]' –
実際に実装する必要がある「折りたたみ」の種類は不思議です。ハスケルでは、 'foldable'がデータ型を指定してリストに相当する' Foldable'クラスを持っています。そして、結果のリストに 'foldr'を使います。他の文脈では、 "fold"は 'recursion-schemes'の' cata'のように_eliminator_のための用語です。私の最初のCS試験では、口頭テストの際に「二分木の折り畳み」を作るように求められました。それは「カタ」のようなものでした。 – chi