Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group elements of a list using Haskell

Tags:

haskell

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
like image 520
Rob Avatar asked Nov 22 '25 06:11

Rob


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
like image 119
Aplet123 Avatar answered Nov 24 '25 23:11

Aplet123