haskell - 在 Haskell map 上求和

标签 haskell map

是否有一个标准函数可以对 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/

相关文章:

c++ - map<..,..> 的第二部分是否稳定?

haskell - 在 Windows 上使用 Stack 编译测试框架时找不到模块 System.Console.MinTTY.Win32

haskell - 幺半群和环之间的差异意味着什么?

csv - 使用 Cassava 在内存中加载 CSV

c++ - 是否可以将默认构造函数设置为 `std::map<T1, T2>` 值?

performance - 游戏 map 网格对网络浏览器的负担有多大?

javascript - 在不首先创建实例的情况下引用方法/使用 jQuery 或任何 javascript 映射函数映射方法

haskell - Haskell 柯里化(Currying)和模式匹配如何协同工作?

algorithm - 如何在 Haskell 中实现 Dijkstra 算法

c++ - 如何访问第二个 map 迭代器?