To start with I have created a Type StudentMark which is a tuple taking firstly a String and secondly an Int.
type StudentMark = (String, Int)
This is my capMarks function:
capMarks :: [StudentMark] -> [StudentMark]
capMarks [cMarks] = [(st, mk) | (st, mk) <- [capMark cMarks]]
And here is my capMark function:
capMark :: StudentMark -> StudentMark
capMark (st, mk)
| mk > 39 = (st, 40)
| mk < 40 = (st, mk)
It is supposed to return:
[("Jo", 37), ("Sam", 40)]
from:
capMarks [("Jo", 37), ("Sam", 76)]
But will only return the correct and expected response when I input just 1 parameter into the function, for example:
capMarks [("Jake", 50)]
Or
capMarks [("Jake"), 30]
But using two (or more) as it's supposed to will just tell me there is a Non-exhaustive pattern in the capMarks function.
Let's analyze your
capMarks
function:First of all
capMarks [cMarks] = ...
is a pattern matching. This matches a list that contains a single element. I assume that you want to do something with an entire list, so change this tocapMarks cMarks = ...
Next
... [(st, mk) | (st, mk) <- [capMark cMarks]]
will apply thecapMark
function to the only element in your original pattern matching scheme and then put the result as the only element of a list. It appears that you want to applycapMark
to each element of a list. So if we follow the previous suggestion, you need to do something like... [capMark mark | mark <- cMarks]
. This does exactly as stated earlier: applycapMark
to each element of thecMarks
list.Final version:
Alternatively, you can also use pattern matching and explicit recursion:
The first line says that
capMarks
applied to an empty list is an empty list. The second line says thatcapMarks
applies to a list with at least one element will applycapMark
to the first element and then recursively applycapMarks
to the rest of the list.This is such a common pattern in Haskell that there is a function called
map
that generalizes it. Usingmap
is incredibly simple:map
has type(a -> b) -> [a] -> [b]
which means it takes a function and a list and returns a list. (Thea
andb
just tell the compiler which types have to be the same.)map
then applies the function to each element in the input list.Eventually you will learn about partial function application and point-free style. With these two concepts, the version using
map
can be simplified slightly:Don't worry too much about this yet. I'm just adding it here for completeness.