Fth*_*der 11 haskell functor applicative traversable foldable
在Applicative深入研究的同时,我来到了Traversable.虽然我已经Foldable从LYHGG知道了,但我还没有见过前者,所以我开始阅读关于Traversable的Haskell wiki.
在阅读它时,我理解为什么它Foldable.fold是平行的Traversable.sequenceA并且Foldable.foldMap是平行的Traversable.traverse.
我也看到每个Traversable也是a Foldable和a Functor,sequenceA并且traversal彼此有默认实现:
traverse f = sequenceA . fmap f
sequenceA = traverse id
Run Code Online (Sandbox Code Playgroud)
所以,正如我在LYHGG中看到的那样,它foldMap是一个最小的完整定义Foldable,我认为,它是平行的traverse,所以fold(它是平行的sequenceA)也是一个最小的完整定义(它不是)... Foldable是不是Functor喜欢Traversable的,所以我们不能申请这个:
foldMap f = fold . fmap f
fold = foldMap id -- this is ok
Run Code Online (Sandbox Code Playgroud)
为什么不是每Foldable一个Functor,Foldable实际上不是一个实例Functor?
作为dfeuer说,Set是一个很好的例子Foldable,是不是一个Functor.
考虑以下类型Set.map:
map :: Ord b => (a -> b) -> Set a -> Set b
Run Code Online (Sandbox Code Playgroud)
请注意,这几乎 是fmap,但它需要一个额外的Ord b约束.由于您有此约束,因此无法将其作为实例Functor.
请注意Set,即使有此限制,它也不是Haskell上的仿函数.鉴于巧妙设置的Eq实例,我们可以违反法律fmap f . fmap g === fmap (f . g).有关进一步的讨论,请参阅此Stack Overflow问题.
如上所述,Set 是 "子类别Hask" 上的(endo)仿函数,其中有序类型为集合,而保留顺序的映射为态射.
因此,即使不明显,我们不能制作Set仿函数的事实实际上暗示了一个真正的数学问题,而不仅仅是我们的类型机器的限制.