简体   繁体   中英

Haskell: How do I combine a list of list of tuples using foldr?

I want to combine my list but I need to pass in a dummy initial value which is why I want to use 'foldr'.

My current list is:

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

I want to combine the list based on their names but I also need to do arithmetic when I am combining the number.

My current code is:

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

This returns an error. I want totalX and totalY to initially be zero so it doesn't mess with the calculations. How do I do this?

Edit: I want my output to be in the same format so I want:

[(1,"Bob J", 4.0],(3,"Bill J", 2.6)]

First I would flatten your list (use concat ), then accumulate the values into a Map recursively. While accumulating, I would ensure that you upsert existing values with addition (this is what the add function does).

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)]]   

Result is

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM