简体   繁体   中英

Haskell couldn't match weird expected type

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM