Typeclasses in Daml(/Haskell) are somewhat analoguous to interfaces, but a bit more flexible (they can be added after the fact, and they can cover multiple types).
I think of a typeclass as a set of related functions that act on a set of related types.
Show
and Eq
are fairly simple typeclasses as they both act on a single type at a time. You can think of the Show
typeclass as having a single function:
class Show a where
show: a -> Text
and you can add the Show
typeclass to any existing type by creating a “typeclass instance” for it, which is the Haskell parlance for defining its implementation:
data Color = Orange | Yellow | Green
instance Show Color where
show c = case c of
Orange -> "Orange"
Yellow -> "Yellow"
Green -> "Green"
Similarly, the Eq
typeclass can be thought of as having two functions:
class Eq a where
(==): a -> a -> Bool
(/=): a -> a -> Bool
(/=) a b = not (a == b)
which defines the types of the two functions, and defines /=
in terms of ==
so that when you implement an instance for that class you only need to provide ==
:
instance Eq Color where
(==) a b = case (a, b) of
(Orange, Orange) -> True
(Yellow, Yellow) -> True
(Green, Green) -> True
_ -> False
Now, let’s say we have a Fruit
type defined as:
data Fruit = FruitOrange | FruitApple | FruitCherry
instance Show Fruit where
show f = case f of
FruitOrange -> "Orange"
FruitApple -> "Apple"
FruitCherry -> "Cherry"
You could imagine a situation where you want to make a function that compares the textual representation of these types:
textEq: (Show a, Show b) => a -> b -> Bool
textEq a b = show a == show b
This function can only work if both of its arguments, which may or may not be of the same type, have a Show
instance, which is expressed by the part before the =>
in the signature.
Or if you want an example of two constraints on the same type, as in the cheatsheet:
sayEq: (Show a, Eq a) => a -> a -> Text
sayEq a b = if a == b
then show a <> " is equal to " <> show b
else show a <> " is not equal to " <> show b
I can’t really come up with a use-case for the specific signature given in the cheatsheet, though: what can you do with Eq
on a single element? 