是否有一个标准函数可以对Haskell映射中的所有值求和。我的地图类似于(a,2),(b,4),(c,6)
本质上,我试图做的是一个归一化的频率分布。因此,上面图中键的值是a,b,c的计数。我需要将它们归一化为(a,1/6),(b,1/3),(c,1/2)。
发布于 2011-12-19 05:01:18
您可以简单地执行Map.foldl' (+) 0 (或者M.foldl',如果您将Data.Map作为M导入)。
这与foldl' (+) 0 . Map.elems类似,但效率略高一些。(不要忘记撇号-使用foldl或foldr对标准数字类型(Int、Integer、Float、Double等)进行求和。)将建立巨大的块,这将消耗大量内存,并可能导致您的程序溢出堆栈。)
但是,只有足够新的containers版本(>= 0.4.2.0)才包含Data.Map.foldl',您不应该使用cabal install对其进行升级,因为它附带GHC。因此,除非你使用的是GHC7.2或更高版本,否则foldl' (+) 0 . Map.elems是实现这一目标的最佳方式。
您也可以使用Data.Foldable.sum,它可以在Foldable类型类的任何实例上工作,但仍然会在常见的数字类型上构建较大的块。
下面是一个完整的示例:
normalize :: (Fractional a) => Map k a -> Map k a
normalize m = Map.map (/ total) m
where total = foldl' (+) 0 $ Map.elems m要使用foldl',您需要导入Data.List。
发布于 2011-12-19 05:02:41
let
total = foldr (\(_, n) r -> r + n) 0 l
in map (\(x, y) -> (x, y/total) l其中l是您的地图。
发布于 2011-12-19 05:07:14
简单:
import qualified Data.Map as M
sumMap = M.foldl' (+) 0
normalizeMap m =
let s = sumMap m in
M.map (/ s) m
main = do
let m = M.fromList [("foo", 1), ("bar", 2), ("baz", 6)]
(print . sumMap) m
(print . normalizeMap) m打印:
9.0
fromList [("bar",0.2222222222222222),("baz",0.6666666666666666),("foo",0.1111111111111111)]https://stackoverflow.com/questions/8554756
复制相似问题