【发布时间】:2020-09-28 22:45:11
【问题描述】:
我想对具有相同键的元组的值求和。
例如,
foo = [(True, 0), (True, 1), (False, 2), (True, -1), (False,4)] :: [(Bool, Int)]
putStrLn . show $ sumTuples foo
应该显示
[(False,6),(True,0)].
当然,这很容易通过Data.Map.fromListWith 实现:
sumTuples :: (Ord a, Num b) => [(a, b)] -> [(a, b)]
sumTuples = Map.toList . Map.fromListWith (+)
但我想在没有Data.Map 的帮助下实现它。
使用过滤器,我可以这样解决:
sumByFilter :: [(Bool, Int)] -> [(Bool, Int)]
sumByFilter xs =
let trues = filter((==True) . fst) xs
falses = filter((==False) . fst) xs
summing = sum . map snd
in [(True, summing trues), (False, summing falses)]
或折叠:
sumByUglyFold :: [(Bool, Int)] -> [(Bool, Int)]
sumByUglyFold =
let initial = [(True, 0), (False, 0)]
in foldl foldingFxn initial
foldingFxn :: [(Bool,Int)] -> (Bool, Int) -> [(Bool, Int)]
foldingFxn [(_, truAcc), (_, falseAcc)] (bool, val)
| bool = [(True, truAcc + val), (False, falseAcc)]
| otherwise = [(True, truAcc), (False, falseAcc + val)]
但是,在这两种情况下,我都将第一个参数硬编码为布尔值。但是,我希望能够对任何未预定义的键执行此操作——当然,如果我有字符串键,我无法对所有键进行模式匹配。
如何使我的代码通用?
【问题讨论】:
标签: dictionary haskell tuples