`instance` declarations

    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.

    Deriving Bits🔗

    The instances derived for the Bits class can be described as follows:

    • For a 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.
    • For a 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.

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

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

    Deriving for isomorphic types🔗

    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) deriving (Literal, Arith)
    five :: Apples
    five = 5
    eatApple :: Apples -\> Apples
    eatApple n = n - 1