I have a List [(String, [(String, Float)]
and want to calculate the average of the floats, so that I get as result [(String, Float)]
. You'll understand reading the code.
type StudentName = String
type CourseName = String
type ExamScore = (CourseName, Float)
type StudentData = [(StudentName, [ExamScore])]
--Delete duplicated entries
filterDuplicates :: StudentData -> StudentData
filterDuplicates [] = []
filterDuplicates sd = [(head sd)] ++ filterDuplicates(filter (\ x -> x /= (head sd)) (tail sd))
--Delete entries whose score is not in scope or whose are not listed the list of course names
filterValidEntries :: [ExamScore] -> [CourseName] -> [ExamScore]
filterValidEntries es cn = filter (\ x -> ((fst x) `elem` cn) && ((snd x) >= 1.0 && (snd x) <= 5.0)) es
--Calulate the average of the cleared data
calculateAverages :: StudentData -> [CourseName] -> [(StudentName, Float)]
calculateAverages sd cn = map createTupel (filterDuplicates sd)
where createTupel x = ((fst x), ((foldr (+) 0 (snd(filterValidEntries(snd x) cn))) / fromIntegral(length (filterValidEntries(snd x) cn))))
Trying to compile this, I am getting the following error:
* Couldn't match expected type `(a0, t0 b)'
with actual type `[ExamScore]'
* In the first argument of `snd', namely
`(filterValidEntries (snd x) cn)'
In the third argument of `foldr', namely
`(snd (filterValidEntries (snd x) cn))'
In the first argument of `(/)', namely
`(foldr (+) 0 (snd (filterValidEntries (snd x) cn)))'
* Relevant bindings include
createTupel :: (a, [ExamScore]) -> (a, b)
(bound at C:\\Users\Lennart\sciebo\Semster 1\Info\Übungen\Übung 06\WI0
4_B06_A04_G01.hs:72:15)
|
72 | where createTupel x = ((fst x), ((foldr (+) 0 (snd(filterValidEntri
es(snd x) cn))) / fromIntegral(length (filterValidEntries(snd x) cn))))
| ^^^^^^^^^^^^^^^^
^^^^^^^^^^^^
I hope you can help me, thank you.
Data.Map
to make it easier to update without adding duplicates to the collection in the first place. – chepner