【发布时间】:2016-03-08 02:18:26
【问题描述】:
在深入研究Applicative的过程中,我来到了Traversable。虽然我已经从LYHGG知道Foldable,但是我还没有看到前者,所以我开始阅读Haskell wiki about Traversable。
阅读时,我明白为什么Foldable.fold 与Traversable.sequenceA 平行,而Foldable.foldMap 与Traversable.traverse 平行。
我还看到每个Traversable 也是一个Foldable 和一个Functor,并且sequenceA 和traversal 在彼此方面都有一个默认实现:
traverse f = sequenceA . fmap f
sequenceA = traverse id
所以,正如我在 LYHGG 中看到的,foldMap 是Foldable 的最小完整定义,我认为它与traverse 平行,所以fold(与sequenceA 平行)也将是一个最小的完整定义(它不是)...Foldable 不像 Traversable 那样是 Functor,所以我们不能应用这个:
foldMap f = fold . fmap f
fold = foldMap id -- this is ok
为什么不是每个Foldable 都是Functor,以及实际上不是Functor 的Foldable 实例是什么?
【问题讨论】:
-
Set是Foldable不是Functor的经典示例。未装箱的向量也是如此。 -
@dfeuer 我将阅读更多关于
Set的信息以了解为什么它不是Functor,但是,集合可以被认为是不重复事物的容器......说,我无法很快弄清楚为什么它不是Functor实例... -
问题是
Functor没有给实现机会来约束它们的类型参数。想象一下,如果有人写了fmap f sf :: Int -> Integer -> Integer。Integer -> Integer类型甚至不是Eq的实例,更不用说Ord,因此在映射时无法检查重复项。该函数可以将多个元素映射到相同的函数,并且您无法折叠重复项。 -
未装箱的向量只能包含“无法装箱”的东西,所以如果
xs :: U.Vector Int、fmap Just xs必须产生U.Vector (Maybe Int)类型的东西,这不是真实的东西。 -
据我了解,
Traversable类是首先构思的(例如,McBride 和 Patterson,"Applicative Programming with Effects";Gibbons 和 Oliveira,"The Essence of the Iterator Pattern")。由于“不是Functors 的容器”问题,Foldable被添加为超类。但是foldMap与Const应用程序不兼容,如 Gibbons 和 Oliveira 的论文所示。
标签: haskell functor applicative foldable traversable