2.6 KiB
+++
title = "class
declarations"
weight = 1
+++
The general concepts behind classes, instances, overloading etc. were introduced in section 2.1. 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):
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.)
Example (from the Prelude):
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:
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 for more detailed insights into the use of functional dependencies.
NOTE: Functional dependencies are not currently checked by the compiler.