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
monad.因此,超类和方法的组合在两种情况下都具有一定的冗余性.
对于monad,可以认为类型类的"更好"定义是(我将跳过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
:虽然>>=
是要比更方便join
日常Haskell的编程(因为你通常需要正是这种组合的fmap
和join
),后者可以更容易把握一个单子是什么.