first commit
This commit is contained in:
commit
13c1ed7b2a
35 changed files with 3330 additions and 0 deletions
86
content/chapter4/page5.md
Normal file
86
content/chapter4/page5.md
Normal file
|
@ -0,0 +1,86 @@
|
|||
+++
|
||||
title = "`class` declarations"
|
||||
weight = 1
|
||||
+++
|
||||
|
||||
The general concepts behind classes, instances, overloading etc. were
|
||||
introduced in section [2.1](fixme). A new class is declared using the
|
||||
following:
|
||||
|
||||
```
|
||||
topDefn ::= class [ context => ] classId {tyVarId }[ | funDep ] where {
|
||||
{varId :: ctxType ; }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
*classId* is the newly declared class. It can be polymorphic, if
|
||||
*tyVarId*'s exist; these are called the *parameters* of the type class.
|
||||
The *tyVarId*'s may themselves be constrained by *context*, in which
|
||||
case the classes named in *context* are called the "super-classes" of
|
||||
this class. The "*varId*`::`*ctxType*" list declares the class method
|
||||
names and their types.
|
||||
|
||||
Example (from the Prelude):
|
||||
|
||||
```hs
|
||||
class Literal a where
|
||||
fromInteger :: Integer -> a
|
||||
```
|
||||
|
||||
This defines the class `Literal`. It says that any type `a` in this
|
||||
class must have a method (a function) called `fromInteger` that converts
|
||||
an `Integer` value into the type `a`. In fact, this is the mechanism the
|
||||
BH uses to interpret literal constants, e.g., to resolve whether a
|
||||
literal like `6`847 is to be interpreted as a signed integer, an
|
||||
unsigned integer, a floating point number, a bit value of 10 bits, a bit
|
||||
value of 8 bits, etc. (This is described in more detail in Section
|
||||
[5.3](fixme).)
|
||||
|
||||
|
||||
Example (from the Prelude):
|
||||
|
||||
```hs
|
||||
class (Literal a) => Arith a where
|
||||
(+) :: a -> a -> a
|
||||
(-) :: a -> a -> a
|
||||
negate :: a -> a
|
||||
(*) :: a -> a -> a
|
||||
```
|
||||
|
||||
|
||||
This defines the class `Arith` with super-class `Literal`. It says that
|
||||
for any type `a` that is a member of the class `Arith`, it must also be
|
||||
a member of the class `Literal`, and it must have four methods with the
|
||||
given names and types. Said another way, an `Arith` type must have a way
|
||||
to convert integer literals into that type, and it must have addition,
|
||||
subtraction, negation and multiplication defined on it.
|
||||
|
||||
|
||||
The optional *funDep* section specifies *functional dependencies*
|
||||
between the parameters of the type class:
|
||||
|
||||
```
|
||||
funDep ::= { {tyVarId }-> {tyVarId }, }
|
||||
```
|
||||
|
||||
These declarations specify that a type parameter may be determined
|
||||
uniquely by certain other type parameters. For example:
|
||||
|
||||
```hs
|
||||
class Add x y z | x y -> z, y z -> x, z x -> y
|
||||
```
|
||||
|
||||
Here, the class declaration says that for any triple of types `x`, `y`
|
||||
and `z` that are in the class `Add`, any two of the types uniquely
|
||||
determines the remaining type, *i.e.,*
|
||||
|
||||
- x and y uniquely determine z,
|
||||
- y and z uniquely determine x, and
|
||||
- z and z uniquely determine y.
|
||||
|
||||
See section [8.1](fixme) for more detailed insights into
|
||||
the use of functional dependencies.
|
||||
|
||||
> **NOTE:**
|
||||
> Functional dependencies are not currently checked by the compiler.
|
Loading…
Add table
Add a link
Reference in a new issue