
Cagdas Ozgenc wrote:
Greetings.
What is the difference between the following two scenarios:
1)
class Eq a where
(==) :: a -> a -> Bool
class Eq a => Ord a where
( < ) :: a -> a -> Bool
Here you are doing subtyping. A variable of type Ord can be substitued for variable of type Eq. (==) belongs to Ord interface.
2)
class Eq a where
(==) :: a -> a -> Bool
class Ord a where
(eq),( < ) :: a -> a -> Bool
instance Ord a => Eq a where
(==) = eq
Here Ord is not a subtype of Eq. Even (eq) and (==) have the same definition, (==) is not part of Ord's interface. You are doing delegation. For those instances of Eq who happens to implement Ord interface, delegate (==) to (eq). The second case is similar to private inheritance in C++. You are overiding the virtual (==) of base class (Eq) in the derived class (Ord), but (==) is not part of derived class' interface.
eq is just a rename for == to avoid the nameclash
The second scenario resembles Russell's Paradox. Typeclass of a typeclass. Anyhow we are loosing orthogonality here.
Thanks