Traversable如何利用它同时继承Foldable和Functor的事实?

Tim*_*Tim 9 haskell functor traversable foldable

class (Functor t, Foldable t) => Traversable t where

    traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
    traverse g = sequenceA . fmap g

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

它如何Traversable同时使用Foldable和继承子类的事实Functor

t如果是可遍历类型,t则它也意味着函子类型和可折叠类型。

我看到的事实t是一个仿函数类型,即fmap,在使用traverse

是在t某处使用的可折叠类型的事实吗?

是否traverse使用t可折叠类型的事实?

使用哪个事实sequenceAt是仿函数类型,t是可折叠类型,还是两者都使用?

我们可以定义一个类,它是Functoronly 的子类,并且以相同的方式定义了traversesequenceA函数吗?

谢谢。

Dan*_*ner 12

Foldable实例未使用。不过,需求Foldable就可以traverse了,因为如果我们可以做一件事情,那么我们可以foldMap做到:

foldMapDefault :: (Traversable t, Monoid m) => (a -> m) -> t a -> m
foldMapDefault f = fst . traverse (\a -> (f a, ()))
Run Code Online (Sandbox Code Playgroud)

这里的基本思想是使用标准的writer monad。由于编写者的绑定操作用于mappend组合“编写的”部分(此处为f a值),因此traversemappend正确的内容组合在一起。(它还会建立一个t ()我们实际上并不关心的东西;丢弃这部分是工作的fst。)

为了简单起见,我使用了编写器monad,但真正的实现使用了稍微弯腰的Const应用程序来避免建立(然后扔掉)无趣的t ()价值。您可能会看到的文件foldMapDefault 在这里和它的实现在这里

  • @dfeuer根据该用户的其他问题,我的判断是,对该用户的一个好的答案应该一次引入一个且只有一个新想法。将遍历转换为折叠已经是一个想法。我只能希望作家monad不再是第二个想法,更不用说不太复杂但也不太流行的“ Const”应用程序了。 (4认同)