xoux
xoux

Reputation: 3494

Why is a typeclass constraint added when I did not define it in my original type definition?

In prelude I am checking some types.

*> let kessel :: (Ord a, Num b) => a -> b -> a; kessel = undefined
*> :t kessel 1 2
kessel 1 2 :: (Num a, Ord a) => a

I don't get why Num a is included as a typeclass constraint on the type of kessel 1 2. It wasn't in the original type definition of kessel. Why does it appear in :t kessel 1 2?

Upvotes: 3

Views: 70

Answers (1)

K. A. Buhr
K. A. Buhr

Reputation: 50929

This is the result of unification of the type of the expression 1 with the type of kessel. Note that the type of the expression 1 is:

> :t 1
1 :: Num p => p

When this type variable p is unified with the type variable a in:

kessel :: (Ord a, Num b) => a -> b -> a

the result is that a has both Ord and Num constraints. In particular:

> :t kessel 1
kessel 1 :: (Ord a, Num b, Num a) => b -> a
>

When you provide the extra argument satisfying Num b => b, you get the final type:

> :t kessel 1 2
kessel 1 2 :: (Ord a, Num a) => a
>

The Num b constraint has been discharged by supplying 2, and neither it nor any other reference to the type b appear in the final signature.

Also, note that if this Num a constraint didn't appear in the final type, then it would be type-correct to write:

> kessel 1 2 :: Bool

since Bool is clearly of type Ord a => a, with the implication that the type of 1 has somehow been unified with Bool.

Upvotes: 13

Related Questions