Reputation: 114
I am new to haskell programming and I wanted to know why I get an error
Non type-variable argument in the constraint: Eq Int
(Use FlexibleContexts to permit this)
when I am trying to define a function like this
union :: (Eq (Int)) => [Int] -> [Int] -> [Int]
Upvotes: 0
Views: 79
Reputation: 477704
You here write:
Eq Int => ...
But this is useless, we know for sure that Int
is an instance of the Eq
typeclass, it is redundant to state that.
Usually you only write type constraints with a type variable in it, for example:
union :: Eq a => [a] -> [a] -> [a]
would indeed require to write such type constraint. In that case we can use a union
for every a
, given that Eq a
holds. This holds given a ~ Int
, but with the latter we can also use it for a ~ Char
, a ~ Maybe Int
, etc.
The idea is that if you write Eq a
, you can use the (==) :: Eq a => a -> a -> Bool
, and (/=) :: Eq a => a -> a -> Bool
function with expressions of type a
. Here however you only use Int
s, so we know for sure that we can do that.
Although from a theoretical perspective, it would not be wrong to write Eq Int
, it is rather "non-sensical".
Upvotes: 5
Reputation: 370445
Type class constraints exist to restrict the types that your function works with. For example if you have the type a -> a -> a
that's a function that needs to be able to handle any type of arguments (as long as both arguments have the same type). If you change it to Eq a => a -> a -> a
, it now only needs to work with arguments of a type that implements Eq
, allowing you to use ==
on the arguments.
In your case you have a function of type [Int] -> [Int] -> [Int]
. That's already as restricted as it gets: The function works specifically with two arguments of type [Int]
- no other types are allowed.
So restricting it to only those types Int
that implement Eq
makes no sense because Int
is already one specific type. So the type should just be [Int] -> [Int] -> [Int]
and you will still be allowed to use ==
because Int
does implement Eq
.
Upvotes: 5