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