Foldable
は のスーパークラスであり、 がおよびのスーパークラスであるのTraversable
と同様です。Functor
Applicative
Monad
の場合と同様に、Monad
基本的に次のように実装できますfmap
。
liftM :: Monad m => (a->b) -> m a -> m b
liftM f q = return . f =<< q
foldMap
次のようにエミュレートすることもできます
foldLiftT :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldLiftT f = fst . traverse (f >>> \x -> (x,x))
-- or: . sequenceA . fmap (f >>> \x -> (x, x))
Monoid m => (,) m
モナドを使う。したがって、スーパークラスとメソッドの組み合わせは、どちらの場合も一定の冗長性を持ちます。
モナドの場合、型クラスの「より良い」定義は次のようになると主張できます (Applicative / monoidal はスキップします)。
class (Functor m) => Monad m where
return :: a -> m a
join :: m (m a) -> m a
少なくともそれが圏論で使われているものです。この定義は、Functor
スーパークラスを使用しないと許可liftM
しないため、この冗長性はありません。
Traversable
クラスで同様の変換が可能ですか?
明確にするために、私が求めているのは再定義です。
class (Functor t, Foldable t) => Traversable t where
skim :: ???
Traverse
実際のメソッドをトップレベル関数にすることができるように
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
しかし、一般的に作ることはできません
instance (Traversable t) => Foldable t where
foldMap = ... skim ...
data T
instance Traversable T where
skim = ...
特定の何かのためにこれが必要なので、私は尋ねていません。と の違いをよりよく理解するための概念的な質問Foldable
ですTraversable
。繰り返しますが、Monad
vs Functor
:とよく似ていますが、毎日の Haskell プログラミング>>=
よりもはるかに便利です (通常、このとの組み合わせがjoin
正確に必要になるため)。fmap
join