wiki page 表示这两个类都处理容器操作,Foldable 是一类在其上定义了 foldr
的容器,而对于 Functor 来说,它是 fmap
。
但是,可折叠类型和仿函数类型之间的根本区别是什么?
维基暗示了这种区别:
但是我仍然不确定为什么一个集合不能被映射来获得另一个集合,如果我正确地解释了它。
最佳答案
Foldable
和 Functor
分别为具有可以折叠(或减少)和映射的结构的类型提供了两个单独的抽象。
Foldable 包含可以枚举和组合在一起的值1。人们可以将可折叠对象视为可以变成列表 ( toList :: Foldable f => f a -> [a]
) 的东西。或者,人们可以将可折叠对象视为其值可以单体组合的结构:(Foldable t, Monoid m) => (a -> m) -> t a -> m
(当然,这需要枚举它们的能力)。
另一方面,仿函数是允许“提升”函数 (a -> b)
以应用于结构 ( a
) 持有的 fmap :: (a -> b) -> (f a -> f b)
的结构。 fmap
必须保留被映射的结构:树前后必须具有相同的形状,列表必须具有相同数量的相同顺序的元素,Nothing
不能变成某物,等等。另一方面,Foldables 不需要保留这种结构;重点是丢弃结构并产生新的结构。
Wiki 指出无法为 fmap
提供类型类约束。 fmap :: (Ord a, Ord b) => (a -> b) -> Set a -> Set b
不与类 fmap :: (a -> b) -> f a -> f b
定义的类型统一,后者没有约束。这使得 Set
的实例无法写入。
然而,这只是一个语言实现问题,而不是关于集合的更深层次的数学陈述。 Foldable 没有 Functor 父类(super class)的真正原因就是 there are Foldable instances which are not Functor instances 。
Proxy s a
持有零级的,Identity a
拥有一个,Maybe a
拥有零或一个,b -> a
持有|b|
一个的,等等。 关于haskell - 为什么 Foldable 和 Functor 是分开的类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33137555/