bluespec-docs/content/chapter4/page5.md

87 lines
2.6 KiB
Markdown
Raw Normal View History

2025-02-12 20:54:12 +00:00
+++
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.