Deriving (Eq, Show)?

Hi All,

The deriving (Eq, Show) ensures the data type can be compared (using == ) and displayed (using show ). The line starting deriving is required for data types used in fields of a template .

Can anyone explain, what is the purpose of using “deriving” for data types. And what does Eq (==) and Show mean ?

any input would be helpfully…

Thank you!

Hi @prajwalhegde3,

Daml works with a concept of “type classes”. @stephen has written a much more complete tutorial about type classes here. You can also consult the Haskell tutorial on type classes, as type classes in Daml are very similar to their Haskell equivalent.

Assuming you’re looking for a more superficial explanation, here’s my attempt at a summary.

A “class” is a set of types that share some property. In Daml, classes can be defined independently of the types that belong to them. So the pieces are:

  1. A class definition.
  2. Any number of data type definitions.
  3. For each type that belongs to the class, an explicit definition of its corresponding behaviour.

As a concrete example, let’s think about how we could define a class for “things that can be compared for equality”, and call it Equality. The class definition could be:

class Equality a where 
  isEqual : a -> a -> Bool

I’m not going to delve deep into the syntax here, but here’s roughly how to read this:

  • The name of the class is Equality, and it is defined on a single type at a time, here left as a parameter a.
  • For a type to belong to this class, it needs to give an implementation of isEqual, which is a function that takes two a arguments and returns a boolean. This should return True when the two values are “equal” and False when they aren’t (this is not expressed in this code snippet and should instead be in documentation).

At this point there is no type anywhere in the world that belongs to Equality, as we haven’t defined any isEqual implementation. Also note that, implicit in our definition of isEqual, this can only ever compare two things of the same type a. If we wanted to compare different types (which arguably is a strange concept for equality, but bear with me), we would have to write a 2-type class:

class EqualityAcrossTypes a b where
  isEqualAcrossTypes : a -> b -> Bool

Now let’s define a data type:

data Person = Person { name: Text, address: Text, ssn: Text }

What does it mean for two persons to be the same? Well, we could decide that, for the purposes of our program, only equality of ssn is necessary, which we would write:

instance Equality Person where
  isEqual p1 p2 = p1.ssn == p2.ssn

Now, in most cases, in programming, we’ll want to consider that two records are equal if all of their fields are equal (recursively). This is the meaning of the built-in Eq class. So the “valid” implementation of Eq for our Person data type here would be:

instance Eq Person where
  (==) p1 p2 = p1.name == p2.name && p1.address == p2.address && p1.ssn == p2.ssn

Eq is only special in that it is defined for primitive types. Here, for example, we build the (==) implementation for Person based on the (==) implementation for Text, which happens to be provided by the base Daml language.

Writing the Eq instance declaration for Person is boring. It’s also a bit error-prone: I could mistype one of these p1 for p2, or forget to add a clause to the definition if I ever add a field to Person. Therefore, to reduce tedium and error rates, the language supports a notion of automatically deriving simple, mechanical instance declarations directly from the data type definition itself.

This is what happens when you say deriving (Eq). After compilation, there is no difference between:

data Person = Person { name: Text, address: Text, ssn: Text }
  deriving (Eq)

and

data Person = Person { name: Text, address: Text, ssn: Text }
instance Eq Person where
  (==) p1 p2 = p1.name == p2.name && p1.address == p2.address && p1.ssn == p2.ssn

but the former is easier to read, less error-prone, and more robust against changes in the future.

1 Like

This is what I was looking for… thank you very much @Gary_Verhaegen