In Haskell, why would you define a function with a type constraint:
ghci> :t (==)
(==) :: (Eq a) => a -> a -> Bool
Rather than defining it so it's type was:
ghci> :t (==)
(==) :: Eq -> Eq -> Bool
You wouldn't do the second version because you'd get a compile error. Eq
is not a type, it's a typeclass. You can't use a typeclass in places where a type is required.
If you did define your own type MyEq
and then define a function ==
with the type MyEq -> MyEq -> Bool
, the expression "hello" == "hello"
would be invalid because "hello"
is a value of type String and not of type MyEq. Since there is no subtyping in haskell a value couldn't be of type String and of type MyEq at the same time.
So if you want to define a function that can accept values of different types which meet certain conditions, you need type classes.