typeclass constrains
In this chapter, we will explore the following scenarios where typeclass constrains are used:
- typeclass constrains in function implementation
- typeclass constrains in class declaration
- typeclass constrains in instance implementation
typeclass constrain in functions
typeclass constrain in the function declaration:
equal3 :: forall a. Eq a => a -> a -> a -> Boolean
equal3 a1 a2 a3 = a1 == a2 && a2 == a3
ain the function declaration is atype, not a valueEq ais the typeclass constrain on typea, which means "for any typeathat has an instance of theEqtypeclass", or "there must exist anEqinstance for typea".
typeclass constrain in class
typeclass constrain in the class signature:
data Ordering = LT | EQ | GT
class Eq a <= Ord a where
compare :: a -> a -> Ordering
- Ord is a subclass of Eq
- Eq is a superclass of Ord
📌 The class constraints in class declarations are used for making a typeclass a subclass of another typeclass.
typeclass constrain in instance
This is also called "Instance Dependencies".
The code below is from the Data.Maybe implementation:
instance showMaybe :: Show a => Show (Maybe a) where
show (Just x) = "(Just " <> show x <> ")"
show Nothing = "Nothing"
The Show instance allows Maybe values to be rendered as a string with show whenever there is an Show instance for the type the Maybe contains.
📌 The class constraints in instance declarations are used to express requirements about the contents of some type.
The following is incorrect, because the type which will make an instance of Eq MUST be a concrete type. Maybe is a type constructor, it is not a concrete type, Maybe a is a concrete type!
instance Eq Maybe where
...