A type can be declared as an instance of a class in two ways. The
general mechanism is the instance
declaration; a convenient shortcut
that can sometimes be used is the deriving
mechanism.
The general instance
declaration grammar is the following:
topDefn ::= instance context => classId {type }where
{ {localDefn ; }}
This can be read as saying that the type type is an instance of class classId, provided the constraints of context hold, and where the localDefn's specify the implementation of the methods of the class.
Sometimes, when a new type is defined using a data
declaration, it can
simultaneously be made a member of certain useful, predefined classes,
allowing the compiler to choose the "obvious" implementation of the
class methods. This is done using the deriving
qualification to a
data
declaration (described in section
4.1) or to a
struct
declaration (described in section
4.2). The only classes for which deriving
can
be used for general types are Bits
, Eq
and Bounded
. Furthermore,
deriving
can be used for any class if the type is a data type that is
isomorphic to a type that has an instance for the derived class.
Bits
🔗The instances derived for the Bits
class can be described as follows:
struct
type it is simply the the concatenation of the bits for
all the fields. The first field is in the leftmost (most significant)
bits, and so on.data
type, all values of the type occupy the same number of
bits, regardless of which disjunct (constructor) it belongs to. This
size is determined by the largest disjunct. The leftmost (most
significant) bits are a code (a tag) for the constructor. As few bits as
possible are used for this. The first constructor in the definition is
coded 0, the next constructor is coded 1, and so on. The size of the
rest of the bits is determined by the largest numbers of bits needed to
encode the fields for the constructors. For each constructor, the fields
are laid out left to right, and the concatenated bits are stored right
justified (i.e., at the least significant bits). For disjuncts that
are smaller than the largest one, the bits between the constructor code
and the field bits, if any, are "don't care" bits.Examples: The type
data Bool = False | True
uses one bit. False
is represented by 0 and True
by 1.
struct Två = { första :: Bit 8; andra:: Bit 16 }
uses 24 bits with första
in the upper 8 bits and andra
in the lower 16.
data Maybe a = Nothing | Just
a will use $1+n$ bits,
where $n$ bits are needed to represent values of type a
. The extra bit
will be the most significant bit and it will be 0 (followed by $n$
unspecified bits) for Nothing
and 1 (followed by the $n$ bits for a
)
for Just
.
Eq
🔗The instances derived for the Eq
class is the natural equality for the
type. For a struct all fields have to be equal, for a data type the
constructors have to be equal and then all their parts.
Bounded
🔗An instance for Bounded
can be derived for an enumeration type,
i.e., a data type where all constructors are niladic. The minBound
will be the first constructor and the maxBound
will be the last.
Bounded
can also be derived for a struct
type if all the field types
of the struct are Bounded
. The minBound
will be the struct with all
fields having their respective minBound
, and correspondingly for
maxBound
.
A data type with one constructor and one argument is isomorphic to its
type argument. For such a type any one-parameter class can be used, in a
deriving
, for which there is an instance for the underlying type.
Example:
data Apples = Apple (UInt 32)
five = 5
eatApple n = n - 1