Haskell: Как мне объединить список списков кортежей, используя foldr? - PullRequest
0 голосов
/ 23 сентября 2018

Я хочу объединить свой список, но мне нужно передать фиктивное начальное значение, поэтому я хочу использовать 'foldr'.

Мой текущий список:

[[(1, "Bob J", 4.0)],[(1, "Bill J", 2.5),(2,"Bill J", 2.7)]]

Я хочу объединить список на основе их имен, но мне также нужно делать арифметику, когда я комбинирую число.

Мой текущий код:

grp xs = foldr combine xs
  where
    combine
    (x,_,y)
    (totalX,_,totalY)
    = (totalX+x,_,totalY+fromIntegral x *y)

Это возвращает ошибку.Я хочу, чтобы totalX и totalY изначально были равны нулю, чтобы это не мешало вычислениям.Как мне это сделать?

Редактировать: я хочу, чтобы мой вывод был в том же формате, поэтому я хочу:

[(1, "Bob J", 4.0], (3, "Билл J ", 2,6)]

1 Ответ

0 голосов
/ 23 сентября 2018

Сначала я бы сгладил ваш список (используйте concat), затем рекурсивно накапливал значения в Map.При накоплении я бы гарантировал, что вы добавите существующие значения с добавлением (это то, что делает функция add).

module Main where                                                                                                                                             

import           Data.List                                                                                                                                    
import qualified Data.Map  as M                                                                                                                               

main = print $ makeMap vals                                                                                                                                   

makeMap :: (Ord k, Num a, Num b) => [(a, k, b)] -> M.Map k (a, b)                                                                                             
makeMap = foldl' go mempty                                                                                                                                    
  where                                                                                                                                                       
    go m (x,name,y) = M.insertWith add name (x,y) m                                                                                                           
    add (a,b) (c,d) = (a+c,b+d)                                                                                                                               

vals = concat [[(1, "Bob J", 4.0)],[(1, "Bill J", 2.5),(2,"Bill J", 2.7)]]   

Результат равен

λ> main                                                                                                                                                       
fromList [("Bill J",(3,5.2)),("Bob J",(1,4.0))] 
...