I am new to Haskell and currently learning about lists.
I have a list of marks
[("Tom", 87, 78, 67), ("Dick", 56, 45, 72)]
and I need to get the sum of marks and the average of it. This is my approach.
Create a function to calculate list of sum of marks of each candidate
sumOfMarks = (\(a, b, c, d) -> b c d)
and map that function to the original list
newList = map sumOfMarks [("Tom", 87, 78, 67), ("Dick", 56, 45, 72)]
create a function to calculate list of average of marks of each candidate
avgList = map (`div`3) newList
merge all the lists original, newList
and avgList
Desired output is
finalList = [("Tom", 87, 78, 67, 232, 77.34), ("Dick", 56, 45, 72, 173, 57.67)]
Another question is - whether this is the best approach to solving the problem and is there a better way?
CodePudding user response:
You can make a function that maps a 4-tuple to a 5-tuple, so the function looks like:
map (\(n, a, b, c) -> (n, a, b, c, …)) oldList
where I leave …
as an exercise.
Note that div :: Integral a => a -> a -> a
is integer division. If you need to work with floats, you can use (/) :: Fractional a => a -> a -> a
. In order to convert Integral
numbers to Fractional
numbers, you can make use of the fromIntegral :: (Integral a, Num b) => a -> b
function.
CodePudding user response:
(Leaving out the conversions necessary to use /
instead of div
)
we can combine the three lists using zipWith3
, or using list comprehensions with zip3
,
finalList =
= zipWith3 (\ (n,a,b,c) s avg -> (n,a,b,c,s,avg))
list newList avgList
= [ (n,a,b,c,s,avg) | ((n,a,b,c), (s, avg)) <-
zip list
(zip newList
avgList) ]
= [ (n,a,b,c,s,avg) | ((n,a,b,c), s, avg) <-
zip3 list
(map sumOfMarks list)
(map (`div` 3) (map sumOfMarks list)) ]
= [ (n,a,b,c,s,avg) | ((n,a,b,c), s, avg) <-
zip3 list
(map sumOfMarks list)
(map ((`div` 3) . sumOfMarks) list) ]
= [ (n,a,b,c,a b c,(a b c)/3)
| (n,a,b,c) <- list ]
= [ (n,a,b,c,s,avg)
| (n,a,b,c) <- list
, let s = a b c
, let avg = s/3 ]
List comprehensions are usually much more visually apparent (i.e. easier to use) than the various combinations of map
s, zip
s, zipWith
s, etc.