Skip to main content

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
  • a in the function declaration is a type, not a value
  • Eq a is the typeclass constrain on type a, which means "for any type a that has an instance of the Eq typeclass", or "there must exist an Eq instance for type a".

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.

warning

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
...