是否有一个标准函数可以对 Haskell 映射中的所有值求和。我的 map 读起来像 [(a,2),(b,4),(c,6)]?
基本上我想做的是归一化频率分布。所以上面映射中键的值是 a,b,c 的计数。我需要将它们归一化为 [(a,1/6),(b,1/3),(c,1/2)]
最佳答案
你可以简单地做 Map.foldl' (+) 0
(或 M.foldl'
,如果您将 Data.Map 导入为 M
)。
这就像foldl' (+) 0 . Map.elems
,但效率稍高一些。 (不要忘记撇号——使用 foldl 或 foldr 对标准数字类型(Int、Integer、Float、Double 等)进行求和会产生巨大的 thunk,这将占用大量内存并可能导致您的程序溢出堆栈。)
但是,只有足够新的 containers 版本(>= 0.4.2.0) 包含 Data.Map.foldl' ,你不应该用 cabal install
升级它,因为它带有 GHC。因此,除非您使用 GHC 7.2 或更高版本,否则 foldl' (+) 0 . Map.elems
是实现这一目标的最佳方式。
您也可以使用 Data.Foldable.sum ,适用于 Foldable 的任何实例typeclass,但仍会在常见的数字类型上构建大的 thunk。
这是一个完整的例子:
normalize :: (Fractional a) => Map k a -> Map k a
normalize m = Map.map (/ total) m
where total = foldl' (+) 0 $ Map.elems m
您需要导入 Data.List 才能使用
foldl'
.
关于haskell - 在 Haskell map 上求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8554756/