wiki page 表示这两个类都处理容器操作,Foldable 是一类在其上定义了 foldr 的容器,而对于 Functor 来说,它是 fmap

但是,可折叠类型和仿函数类型之间的根本区别是什么?

维基暗示了这种区别:



但是我仍然不确定为什么一个集合不能被映射来获得另一个集合,如果我正确地解释了它。

最佳答案

FoldableFunctor 分别为具有可以折叠(或减少)和映射的结构的类型提供了两个单独的抽象。

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

  • “保持”是有点松,并打算在"Functors are containers"意义上解释,其中Proxy s a持有零级的,Identity a拥有一个,Maybe a拥有零或一个,b -> a持有|b|一个的,等等。
  • 关于haskell - 为什么 Foldable 和 Functor 是分开的类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33137555/

    10-13 07:46