除了可折叠之外,Traversable还有什么"独特的方法"?

lef*_*out 8 containers haskell fold traversable

Foldable是一个超类Traversable,类似于Functor超类的ApplicativeMonad.

类似的情况下Monad,它可以基本上实现fmap

liftM :: Monad m => (a->b) -> m a -> m b
liftM f q = return . f =<< q
Run Code Online (Sandbox Code Playgroud)

我们也可以效仿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))
Run Code Online (Sandbox Code Playgroud)

使用Monoid m => (,) mmonad.因此,超类和方法的组合在两种情况下都具有一定的冗余性.

对于monad,可以认为类型类的"更好"定义是(我将跳过applicative/monoidal)

class (Functor m) => Monad m where
  return :: a -> m a
  join :: m (m a) -> m a
Run Code Online (Sandbox Code Playgroud)

至少那是在类别理论中使用的.这个定义,不使用Functor超类,容许liftM,所以它是没有这个冗余.

类是否可以进行类似的转换Traversable


澄清一下:我所追求的是重新定义,让我们称之为,

class (Functor t, Foldable t) => Traversable t where
  skim :: ???
Run Code Online (Sandbox Code Playgroud)

这样我们就可以使实际Traverse方法成为顶级函数

sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
Run Code Online (Sandbox Code Playgroud)

但它会不会有可能使一般

instance (Traversable t) => Foldable t where
  foldMap = ... skim ...

data T
instance Traversable T where
  skim = ...
Run Code Online (Sandbox Code Playgroud)

我不是在问,因为我需要特别的东西; 这是一个概念性的问题,以便更好地理解之间的差异FoldableTraversable.同样很像MonadVS Functor:虽然>>=是要比更方便join日常Haskell的编程(因为你通常需要正是这种组合fmapjoin),后者可以更容易把握一个单子是什么.

J. *_*son 3

Foldableis to Functoras Traversableis to Monad,即 和Foldable是 和的Functor超类(对所有应用/单子提案噪声取模)。MonadTraversable

确实,这已经在代码中了

instance Foldable f => Traversable f where
  ...
Run Code Online (Sandbox Code Playgroud)

因此,尚不清楚还想要什么。whileFoldable的特点是最终不仅取决于能够像列表一样将内容抽象出来,而且还能够提取形状toList :: Foldable f => f a -> [a]TraversabletoList

shape :: Functor f => f a -> f ()
shape = fmap (const ())
Run Code Online (Sandbox Code Playgroud)

然后重新组合它们

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
Run Code Online (Sandbox Code Playgroud)

这取决于traverse.

有关此属性的更多信息,请参阅Russell O'Connor 的博客文章

  • 我也许会说 Foldable 之于 Functor 就像 Traversable 之于 *Applicative* 一样。 (2认同)
  • 如果我们有依赖类型,我们可以写“combine :: Traversable f =&gt; Πx:f ()”。Vec a(长度x)-&gt; fa`。我们可以在不使用依赖类型的情况下创建 Traversable 类,这一事实有点令人惊奇。这可能与它使用应用函子的辅助类并假设它们遵循它们的定律有关。 (2认同)