Reputation: 157
I have an a list of data with the format [(StudID,Int)]
where type StudID = String
. Hence, I have a set of data:
marks = [("8",90),("10",100),("5",86),("3",45)]
I now want to obtain the second value based on a matching ID which is the first element in each tuple. For example, if the ID
I'm looking for is "5"
then I want the value of 86
and so on. I tried something as below:
getStudMarks :: StudID -> [(StudID,Int)] -> Int
getStudMarks studid [(id,mark):xs] = if studid == id then mark else getStudMarks studid xs
But I'm getting thrown
Couldn't match expected type ‘(StudID, Int)’ with actual type ‘[(StudID, Int)]’
highlighting the [(id,mark):xs]
section in my code
Am I doing the recursion correctly?
Upvotes: 1
Views: 123
Reputation: 1764
The recursion should be
getStudMarks studid [] = error "No value for id"
getStudMarks studid ((id,mark):xs)
| studid == id = mark
| otherwise = getStudMarks studid xs
Other possibility
getStudMarks id [] = error "No value for id"
getStudMarks studid ((id,mark):xs) = if studid == id then mark else getStudMarks studId xs
Inspired by LearnYouAHaskell
Upvotes: 0
Reputation: 531345
(id, mark):xs
is the list you want to pattern-match on; you are wrapping that in another layer of brackets that implies a value of type [[(StudID, Int)]]
.
getStudMarks studid ((id,mark):xs) = if studid == id then mark else getStudMarks studid marks.
However, you also need to consider what happens if getStudMarks
ever receives an empty list as its second argument, which will happen if studid
is never found.
getStudMarks _ [] = ???
Compare your function to lookup :: Eq => a -> [(a,b)] -> Maybe b
(which, incidentally is all you really need here; change the type of getStudMarks
, write getStudMarks = lookup
, and you're done).
Upvotes: 3
Reputation: 20843
Have you had a look at list comprehension?
getStudMarks studentId marks = [ id | (student, id) <- marks, student == studentId ]
Upvotes: 1