Как я могу суммировать список кортежей в Haskell?

#haskell

#haskell

Вопрос:

Это очень простой вопрос, но, похоже, я не могу найти ответ. Допустим, у меня есть список кортежей в Haskell,

 myList = [("foo", 2), ("bar", 4), ("foo", 6), ("bar", 1)]
 

и я хочу сгруппировать их по их первым элементам и суммировать их по второму, как мне это сделать?

Этот пример приведет к [("foo", 8), ("bar", 5)]

Ответ №1:

Это сильно зависит от того, является ли ваш ключ (первый элемент в вашем кортеже) Ord или только Eq . Если это только in Eq , то partition подход, основанный на a, подходит:

 import Data.List (partition)

sumByKey :: (Eq k, Num v) => [(k, v)] -> [(k, v)]
sumByKey []         = []
sumByKey ((k,v):xs) = (k,v   sum vs) : sumByKey bs
  where
    vs       = map snd ks
    (ks, bs) = partition ((k ==) . fst) xs
 

Однако, если у вас есть Ord под рукой и у вас все в порядке с внешними зависимостями, Map вы можете сделать код намного проще:

 import Data.Map.Strict

sumByKey :: (Ord k, Num v) => [(k, v)] -> [(k, v)]
sumByKey = toList . fromListWith ( )