8

Foldableは のスーパークラスであり、 がおよびのスーパークラスであるのTraversableと同様です。FunctorApplicativeMonad

の場合と同様に、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。繰り返しますが、Monadvs Functor:とよく似ていますが、毎日の Haskell プログラミング>>=よりもはるかに便利です (通常、このとの組み合わせjoin正確に必要になるため)。fmapjoin

4

2 に答える 2

3

Foldableto は toFunctorそのままTraversableですMonad。つまりFoldable、 andはandFunctorのスーパークラスです(すべてのアプリカティブ/モナド提案ノイズを法とする)。MonadTraversable

確かに、それはすでにコードに含まれています

instance Foldable f => Traversable f where
  ...

したがって、さらに何が必要かは明らかではありません。whileFoldableの特徴は、リストのようにコンテンツを抽象化できるだけでなく、形状を抽出できることに最終的に依存します。toList :: Foldable f => f a -> [a]TraversabletoList

shape :: Functor f => f a -> f ()
shape = fmap (const ())

そしてそれらを再結合します

combine :: Traversable f => f () -> [a] -> Maybe (f a)
combine f_ = evalStateT (traverse pop f_) where
  pop :: StateT [a] Maybe a
  pop = do x <- get
           case x of
             [] = empty
             (a:as) = set as >> return a

に依存しtraverseます。

このプロパティの詳細については、Russell O'Connor によるこのブログ投稿を参照してください。

于 2014-01-13T03:42:38.373 に答える