可折叠与可穿越

Foldable vs Traversable

在深入研究Applicative的过程中,我来到了Traversable。虽然我已经从LYHGG, I haven't seen the former yet, so I started reading the Haskell wiki about Traversable.

知道了Foldable

看的时候明白了为什么Foldable.fold平行于Traversable.sequenceAFoldable.foldMap平行于Traversable.traverse

我还看到每个 Traversable 也是一个 Foldable 和一个 Functor,并且 sequenceAtraversal 在彼此条件:

traverse f = sequenceA . fmap f
sequenceA = traverse id

所以,正如我在 LYHGG 中看到的那样,foldMapFoldable 的最小完整定义,我认为它与 traverse 平行,所以 fold(与 sequenceA 平行)也将是一个最小的完整定义(它不是)... Foldable 不像 Traversable 那样是 Functor,所以我们不能应用这个:

foldMap f = fold . fmap f
fold = foldMap id -- this is ok

为什么不是每个 Foldable 都是 Functor,什么是 Foldable 实际上不是 Functor 的实例?

正如 dfeuer 所说,SetFoldable 的一个很好的例子,它不是 Functor

考虑Set.map的类型:

map :: Ord b => (a -> b) -> Set a -> Set b

请注意,这几乎是 fmap,但它需要额外的 Ord b 约束。由于您有此约束,因此无法将其作为 Functor.

的实例

请注意,即使有此限制,Set 也不是 Haskell 上的函子。通过巧妙地设置 Eq 个实例,我们可以打破 fmap f . fmap g === fmap (f . g) 的规律。请参阅此 Stack Overflow question 以进行进一步讨论。

如此处所述,Set "subcategory of Hask" 上的一个 (endo) 函子,其有序类型为集合,并具有 顺序- 将映射 保留为态射。

因此,即使不明显,我们不能使 Set 成为函子这一事实实际上暗示了一个真正的数学问题,而不仅仅是我们类型类机制的限制。