Haskell 为什么没有折叠';方法?

Haskell 为什么没有折叠';方法?,haskell,big-o,lazy-evaluation,fold,monoids,Haskell,Big O,Lazy Evaluation,Fold,Monoids,我注意到Foldable类包含fold、foldl、foldr、foldl'和foldr',但是没有fold'(对于严格的单向折叠) 我如何用IntMap(实现为树,但不提供对内部节点的直接访问)模拟fold的行为 动机: 特别是,如果我有一个包含大小为K的M个IntMap(总大小N=M*K)的IntMap,我希望在O(N*log(M))big-O运行时合并它们。比如: unionMaps :: IntMap (IntMap a) -> IntMap a unionMaps = fol

我注意到Foldable类包含fold、foldl、foldr、foldl'和foldr',但是没有fold'(对于严格的单向折叠)

我如何用IntMap(实现为树,但不提供对内部节点的直接访问)模拟fold的行为


动机:

特别是,如果我有一个包含大小为K的M个IntMap(总大小N=M*K)的IntMap,我希望在O(N*log(M))big-O运行时合并它们。比如:

unionMaps :: IntMap (IntMap a) -> IntMap a
unionMaps = fold'
这将起作用,因为IntMap是一个Monoid实例,mappend定义为union。请注意,一般来说,使用foldl'或foldr'理论上较慢,因为它需要ω(N*logn)最坏情况下的运行时间。诚然,这在实践中可能是一个微不足道的差异,但我学究式地关心理论上的最佳界限



哎呀,上面是错的。我更仔细地研究了它,现在我意识到无论您使用fold、foldl还是foldr,运行时间都将以O(N*log(M))为单位。因此,我对这个问题不再有任何动机。

因为我找不到任何具有完整的
可折叠的
折叠'
,为了回答基本问题,我从上面的评论中为@Carl的建议写了一些代码(仅限WHNF):


对于
IntMap
元素,
fold
和假设的
fold'
之间有什么区别<代码>联合
是严格的。当结果被要求时,它将同时执行整个树的联合值。哦,我没有意识到这一点。我想一般来说,如果我使用一个幺半群,mappend的参数是严格的,我可以得到相同的结果。有没有一种简单的方法来获取一个幺半群,并用一个参数严格的相同幺半群来替换它?好吧,我想你可以编写几个新类型的包装器来强制它们的输入——例如,一个用于WHNF,另一个用于NF。然后,
foldMap
将应用包装器并同时进行单项式组合。事实上,我一直在考虑这一点,我意识到我的运行时间分析只适用于Intmap不仅高度平衡,而且重量平衡的情况。我认为这并不能保证,所以最好的方法可能是将值提取到一个列表中,然后编写一个更智能的unionsWith函数。为了在合并成本方面达到理想效果,您应该使用类似于Huffman算法的方法。但是,您引入了额外的簿记,这可能会大大超过合并成本的节约。玩得高兴
{-# LANGUAGE BangPatterns #-}
import Data.Monoid
import Data.Foldable

newtype StrictM m = StrictM { getStrict :: m }

instance Monoid m => Monoid (StrictM m) where
    mempty = StrictM mempty
    mappend (StrictM !x) (StrictM !y) = StrictM (mappend x y)

fold' :: (Foldable t, Monoid m) => t m -> m
fold' = getStrict . foldMap StrictM