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可折叠类型的事实?
使用哪个事实sequenceA:t是仿函数类型,t是可折叠类型,还是两者都使用?
我们可以定义一个类,它是Functoronly 的子类,并且以相同的方式定义了traverse和sequenceA函数吗?
谢谢。
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值),因此traverse将mappend正确的内容组合在一起。(它还会建立一个t ()我们实际上并不关心的东西;丢弃这部分是工作的fst。)
为了简单起见,我使用了编写器monad,但真正的实现使用了稍微弯腰的Const应用程序来避免建立(然后扔掉)无趣的t ()价值。您可能会看到的文件foldMapDefault 在这里和它的实现在这里。