Instance Declarations

Viewed 1126

Bit curious why the instance declaration is needed in the following as a default implementation is provided.

module Example where

class Eq a => EQ a where
    eq :: a -> a -> Bool
    eq = (==)

-- why is this instance declaration needed?
instance EQ Int where
    eq = (==)

f :: Int -> Int -> Bool
f = eq

If I leave out the instance declaration I get an error. I'm sure it's explained somewhere in the Haskell report but it will take a while to find it.

1 Answers

I think you're definition of a class, is probably more what in Java/C#/... is a class.

If you write:

class Eq a => EQ a where
    eq :: a -> a -> Bool
    eq = (==)

You only define a typeclass: a way to add functions to a type class and write restrictions. You have not written that every Eq a is an EQ a... You have written that in order to implement EQ a, you have to implement Eq a as well (which is a bit weird here).

Furthermore you have provided a default implementation: eq = (==), but that is only a default implementation for an instance where you do not specify the implementation.

By writing:

instance EQ Int where
    eq = (==)

you have now defined that Int is an EQ. You can make the instance more useful by writing for instance:

instance Eq a => EQ a

Now you have written than all types a for which Eq a holds, also are a type instance of EQ. If you write that however, you have immediately defined the entire universum of EQ since in your class definition, you restricted a to be an instance of EQ, so that means that now, in the entire Haskell universe, eq is equal to (==).

You probably want to say:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

class EQ a where
    eq :: a -> a -> Bool

instance Eq a => EQ a where
    eq = (==)

Now you defined a typeclass EQ and for every type a that is Eq a, we set eq to (==), but it allows you to define an EQ over other types as well, like data Foo that is not an instance of Eq. Mind that we have to turn on two extensions here. These are compiler specific, and thus are not part of standard Haskell.

Related