Group elements of a list using Haskell

Viewed 102

I'm trying to group the elements of this list based on the value of the first item of each, but can't make it work.

I'm trying to get [("A",[("EXP1",5),("EXP2", 9)],("B",[("EXP15",8),("EXP24", 4)]] but I get errors:

import Data.Function (on)
import Data.List (sortBy, groupBy)
import Data.Ord (comparing)
    

myGroupElem :: (Eq a, Ord a) => [(a, b, c)] -> [(a, [(b,c)])]
myGroupElem = map (\l -> (fst . head $ l, map (b,c)  l)) . groupBy ((==) `on` fst)
          . sortBy (comparing fst)          

lData = [("A", "EXP1", 5),("A", "EXP2", 9),("B", "EXP15", 8),("C", "EXP16", 7),("B", "EXP24", 4)]

main = do
       print $ myGroupElem lData
1 Answers

Here's the fixed code:

import Data.Function (on)
import Data.List (sortBy, groupBy)
import Data.Ord (comparing)

fst3 :: (a, b, c) -> a
fst3 (x, _, _) = x

next2 :: (a, b, c) -> (b, c)
next2 (_, b, c) = (b, c)

myGroupElem :: (Eq a, Ord a) => [(a, b, c)] -> [(a, [(b,c)])]
myGroupElem = map (\l -> (fst3 . head $ l, map next2 l)) . groupBy ((==) `on` fst3)
          . sortBy (comparing fst3)

lData = [("A", "EXP1", 5),("A", "EXP2", 9),("B", "EXP15", 8),("C", "EXP16", 7),("B", "EXP24", 4)]

main = do
       print $ myGroupElem lData

Your code had two main issues: the first being your use of fst, which is only defined on 2-tuples. So, I made a fst3 that works on 3-tuples. The other was map (b,c) l, which is not a valid lambda. So, I made a next2 function that gets the last two elements of 3-tuples, and map with that instead. You could also just use a lambda:

map (\(_, b, c) -> (b, c)) l
Related