Prelude's Type Classes
Relationships
Below is a dependency graph / type class categorization of the type classes found in Prelude. The usage frequency key is my current understanding and may be inaccurate for the "somewhat"/"rare" type classes:
Tricks for Implementing a Type Class Instance
Keep in mind that when implementing a type class, one does not always need to implement its function with a specific implementation for a given type. There are two situations in which this can occur:
First, this situation can arise when a type class defines two or more functions. Sometimes, a function in a type class can be defined using another function from that same type class. Take, for example, the Eq
type class:
class Eq a where
eq :: a -> a -> Boolean
notEq :: a -> a -> Boolean
Granted, an Eq
instance can be derived by the compiler. However, assuming this wasn't the case, there are two ways we could implement it:
- We could implement only
eq
and implementnotEq
by invertingeq
's result. - We could implement only
notEq
and implementeq
by invertingnotEq
's result
Second, sometimes, a function in a type class can be defined using a function from a required type class. Take, for example, the Ord
type class:
data Ordering
= LT
| EQ
| GT
class (Eq a) <= Ord a where
compare :: a -> a -> Ordering
If we implement compare
, we can also implement eq
:
data ColoredBox
= RedBox
| GreenBox
instance Ord ColoredBox where
compare RedBox GreenBox = LT
compare GreenBox RedBox = GT
compare _ _ = EQ {- which expands to...
compare RedBox RedBox = EQ
compare GreenBox GreenBox = EQ
-}
instance Eq ColoredBox where
eq a b = (compare a b) == EQ
notEq a b = (compare a b) /= EQ