first commit
This commit is contained in:
commit
13c1ed7b2a
35 changed files with 3330 additions and 0 deletions
113
content/chapter4/page6.md
Normal file
113
content/chapter4/page6.md
Normal file
|
@ -0,0 +1,113 @@
|
|||
+++
|
||||
title = "`instance` declarations"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
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](fixme)) or to a
|
||||
`struct` declaration (described in section
|
||||
[4.2](fixme)). 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` {#sec-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
|
||||
|
||||
```hs
|
||||
data Bool = False | True
|
||||
```
|
||||
|
||||
uses one bit. `False` is represented by 0 and `True` by 1.
|
||||
|
||||
```hs
|
||||
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.
|
||||
|
||||
```hs
|
||||
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:
|
||||
|
||||
```hs
|
||||
data Apples = Apple (UInt 32) deriving (Literal, Arith)
|
||||
five :: Apples
|
||||
five = 5
|
||||
eatApple :: Apples -\> Apples
|
||||
eatApple n = n - 1
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue