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