Reputation: 3494
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
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