jazzer97
jazzer97

Reputation: 157

Getting data elements through match

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

Answers (3)

SBylemans
SBylemans

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

chepner
chepner

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

Micha Wiedenmann
Micha Wiedenmann

Reputation: 20843

Have you had a look at list comprehension?

getStudMarks studentId marks = [ id | (student, id) <- marks, student == studentId ]

Upvotes: 1

Related Questions