我注意到Foldable类包含fold,foldl,foldr,foldl'和foldr'但是没有折叠' (对于严格的幺半褶)
我如何模仿fold'的行为?使用IntMap(实现为树,但不能直接访问内部节点)。
动机:
特别是,如果我有一个包含大小为K的N IntMap的IntMap(总大小为N = M * K),我想在O中合并它们(N * log(M) )大O运行时间。类似的东西:
unionMaps :: IntMap (IntMap a) -> IntMap a
unionMaps = fold'
这样可行,因为IntMap是Monoid的一个实例,mappend定义为union。请注意,一般来说,使用foldl'或者折叠'理论上较慢,因为它需要Omega(N * log N)最坏情况下的运行时间。不可否认,这在实践中可能是一个微不足道的差异,但我迂腐足以关心理论上的最佳界限
答案 0 :(得分:3)
由于我无法找到任何包含完整Foldable
fold'
的图书馆,为了回答基本问题,我为@ Carl的建议编写了一些代码。以上评论(仅限WHNF):
{-# 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