【发布时间】:2016-06-22 16:42:31
【问题描述】:
我正在查看 Haskell 中的 Foldable 课程。 fold、foldMap 中的两个方法需要一个 Monoid 实例。但是foldr 或foldl 没有这样的限制。
fold :: Monoid m => t m -> m
foldMap :: Monoid m => (a -> m) -> t a -> m
foldr :: (a -> b -> b) -> b -> t a -> b
foldl :: (b -> a -> b) -> b -> t a -> b
为了foldr/foldl 的结果是等价的,它不应该限制给定的折叠函数是关联的吗?有没有同一个list中foldr/foldl的结果不同的例子?
Foldable 实例不应该包装 Monoidal 值吗?还是 Foldable 更通用?
【问题讨论】:
-
看
foldr和foldl的第一个函数的类型。一个幺半群不适合那里。 -
@pdexter 不,Monoid 是唯一对标准折叠真正有意义的东西,因为一切都被视为“某种列表”。无论类型被视为具有更复杂的结构,名称中的“左”和“右”都不再有意义。如果你想折叠任何不是列表的东西,你真的必须提供更复杂的代数。
-
函数组合是关联的:
foldr :: (a -> b -> b) -> b -> t a -> b,foldr (c :: (a -> b -> b)) :: b -> t a -> b,c (x :: a) :: b -> b,所以我们可以组合c x1,@987654335 @, ...,c xn以我们喜欢的任何顺序,因为 / IOW 内函数 do 形成了一个幺半群,Endo b,所有这些都是自己的。与例如列表,(x :) == ([x] ++),即我们可以用一些合适的f和c x . c y ~= f x <> f y将c表示为c x = (f x <>)。 (或类似的东西)。
标签: haskell fold monoids foldable