I am writing a function called mapper2
that applies a function to two lists:
mapper2 :: (a-> b -> c) -> [a] -> [b] -> [c]
mapper2 f (
Silvio Mayolo has covered the main, practical part of the question, so I will stick to the technical details related to...
what the error means?
To begin with, the error is a bit hairy, but one thing that you can focus on at first is the Num (b -> c)
bit. It indicates that you are somehow trying to use a function type (b -> c
) as a number (i.e. an instance of Num
), which is something that is almost never done intentionally (as we usually do not use functions as numbers). More often than not, when such things happen it is a sign that there is a mismatch in the number of arguments somewhere (which is the case here, as explained by Silvio Mayolo's answer). That said, what follows is an explanation of how the error comes about.
The first argument of mapper2
has type a -> b -> c
or, equivalently, a -> (b -> c)
. When you pass...
(\x -> x * 2) :: Num z => z -> z
... to it, a -> (b -> c)
and Num z => z -> z
are matched (or, using the jargon, unified), so that the first z
becomes a
and the second z
becomes b -> c
. Since both z
are supposed to be the same thing, a
becomes b -> c
as well, and so the type of (\x -> x * 2)
is specialised to:
(\x -> x * 2) :: Num (b -> c) => (b -> c) -> (b -> c)
The error message Non type-variable argument in the constraint: Num (b -> c)
refers to how, unlike in e.g. Num x
, there is something within the constraint that is not a type variable. In this case, it is function type constructor, ->
. While turning on the FlexibleContexts
extension, as the error message suggests, would allow that, there is no reason to do so here, as it still wouldn't be what you want (you have no intention of using functions as numbers). Furthermore, doing so in this case would just lead to another type error.