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.
A minor, but important, comment on style. Haskell function application is never written f(x+y)
without space between the f
and (
. It's always written f (x+y)
.
Anyway, here's how to figure out this error message. The important bits are that GHC expected a type of the form (a, tb)
-- the a
, t
, and b
are less important than the fact that it expected a tuple (ie, pair) type, but it was given an [ExamScore]
, which is clearly a list and not the tuple it expected.
Where did this happen? Well, as the error message says, the problem occurred in trying to pass the first argument to snd
-- namely (filterValidEntries (snd x) cn)
.
Note that snd
, since it grabs the second element of a tuple, obviously expected a tuple. Yet, the argument filterValidEntries (snd x) cn
does not return a tuple, it actually returns a list [ExamScore]
.
That's your problem. Did you really intend to pass the argument filterValidEntries (snd x) cn
, which returns a list, to the function snd
, which expects a tuple? No, you did not. What were you trying to do? Maybe map snd
to each element of the list?
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.