Foldable
是 的超类Traversable
,类似于andFunctor
的超类。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
单子。所以超类和方法的结合在这两种情况下都有一定的冗余。
在单子的情况下,可以说类型类的“更好”定义将是(我将跳过应用程序/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 编程更方便(因为你通常需要和的这种组合),但后者更容易掌握 monad 的含义。fmap
join