Dipesh Desai
Dipesh Desai

Reputation: 114

Rigid Usage of Int in Haskell functions

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

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

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 Ints, 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

sepp2k
sepp2k

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

Related Questions