4 Declarations and Bindings
In this chapter, we describe the syntax and informal semantics of Haskell declarations.
The declarations in the syntactic category let or where construct).
For exposition, we divide the declarations into three groups: user-defined datatypes, consisting of type, newtype, and data declarations (SectionΒ 4.2); type classes and overloading, consisting of class, instance, and default declarations (SectionΒ 4.3); and nested declarations, consisting of value bindings, type signatures, and fixity declarations (SectionΒ 4.4).
Haskell has several primitive datatypes that are βhard-wiredβ (such as integers and floating-point numbers), but most βbuilt-inβ datatypes are defined with normal Haskell code, using normal type and data declarations. These βbuilt-inβ datatypes are described in detail in SectionΒ 6.1.
4.1 Overview of Types and Classes
Haskell uses a traditional Hindley-Milner polymorphic type system to provide a static type semantics [4], [5], but the type system has been extended with type classes (or just classes) that provide a structured way to introduce overloaded functions.
A class declaration (SectionΒ 4.3.1) introduces a new type class and the overloaded operations that must be supported by any type that is an instance of that class. An instance declaration (SectionΒ 4.3.2) declares that a type is an instance of a class and includes the definitions of the overloaded operationsβcalled class methodsβinstantiated on the named type.
For example, suppose we wish to overload the operations (+) and negate on types Int and Float. We introduce a new type class called Num:
class Num a where -- simplified class declaration for Num
(+) :: a -> a -> a -- (Num is defined in the Prelude)
negate :: a -> aThis declaration may be read βa type a is an instance of the class Num if there are class methods (+) and negate, of the given types, defined on it.ββ
We may then declare Int and Float to be instances of this class:
instance Num Int where -- simplified instance of Num Int
x + y = addInt x y
negate x = negateInt x
instance Num Float where -- simplified instance of Num Float
x + y = addFloat x y
negate x = negateFloat xwhere addInt, negateInt, addFloat, and negateFloat are assumed in this case to be primitive functions, but in general could be any user-defined function. The first declaration above may be read βInt is an instance of the class Num as witnessed by these definitions (i.e.Β class methods) for (+) and negate.β
More examples of type classes can be found in the papers by Jones [6] or Wadler and Blott [7]. The term βtype classβ was used to describe the original Haskell 1.0 type system; βconstructor classβ was used to describe an extension to the original type classes. There is no longer any reason to use two different terms: in this report, βtype classβ includes both the original Haskell type classes and the constructor classes introduced by Jones.
4.1.1 Kinds
To ensure that they are valid, type expressions are classified into different kinds, which take one of two possible forms:
- The symbol
represents the kind of all nullary type constructors.β - If
andπ 1 are kinds, thenπ 2 is the kind of types that take a type of kindπ 1 β π 2 and return a type of kindπ 1 .π 2
Kind inference checks the validity of type expressions in a similar way that type inference checks the validity of value expressions. However, unlike types, kinds are entirely implicit and are not a visible part of the language. Kind inference is discussed in SectionΒ 4.6.
4.1.2 Syntax of Types
| (function type) | |||
| (type application) | |||
| (tuple type, | |||
| (list type) | |||
| (parenthesized constructor) | |||
| (unit type) | |||
| (list constructor) | |||
| (function constructor) | |||
| (tupling constructors) |
The syntax for Haskell type expressions is given above. Just as data values are built using data constructors, type values are built from type constructors. As with data constructors, the names of type constructors start with uppercase letters. Unlike data constructors, infix type constructors are not allowed (other than (->)).
The main forms of type expression are as follows:
Type variables, written as identifiers beginning with a lowercase letter. The kind of a variable is determined implicitly by the context in which it appears.
Type constructors. Most type constructors are written as an identifier beginning with an uppercase letter. For example:
Char,Int,Integer,Float,DoubleandBoolare type constants with kind .β MaybeandIOare unary type constructors, and treated as types with kind .β β β - The declarations
data T ...ornewtype T ...add the type constructorTto the type vocabulary. The kind ofTis determined by kind inference.
Special syntax is provided for certain built-in type constructors:
- The trivial type is written as
()and has kind . It denotes the βnullary tupleβ type, and has exactly one value, also writtenβ ()(see SectionΒ 3.9 and SectionΒ 6.1.5). - The function type is written as
(->)and has kind .β β β β β - The list type is written as
[]and has kind .β β β - The tuple types are written as
(,),(,,), and so on. Their kinds are ,β β β β β , and so on.β β β β β β β
Use of the
(->)and[]constants is described in more detail below.Type application. If
is a type of kindπ‘ 1 andπ 1 β π 2 is a type of kindπ‘ 2 , thenπ 1 is a type expression of kindπ‘ 1 π‘ 2 .π 2 A parenthesized type, having form
, is identical to the type( π‘ ) .π‘
For example, the type expression IO a can be understood as the application of a constant, IO, to the variable a. Since the IO type constructor has kind a and the whole expression, IO a, must have kind
Special syntax is provided to allow certain type expressions to be written in a more traditional style:
- A function type has the form
, which is equivalent to the typeπ‘ 1 β π‘ 2 . Function arrows associate to the right. For example,( β ) π‘ 1 π‘ 2 Int -> Int -> FloatmeansInt -> (Int -> Float). - A tuple type has the form
, where( π‘ 1 , β¦ , π‘ π ) , which is equivalent to the typeπ β₯ 2 where there are( , β¦ , ) π‘ 1 β¦ π‘ π commas between the parenthesis. It denotes the type ofπ β 1 -tuples with the first component of typeπ , the second component of typeπ‘ 1 , and so on (see SectionΒ 3.8 and SectionΒ 6.1.4).π‘ 2 - A list type has the form
, which is equivalent to the type[ π‘ ] . It denotes the type of lists with elements of type[ ] π‘ (see SectionΒ 3.7 and SectionΒ 6.1.3).π‘
These special syntactic forms always denote the built-in type constructors for functions, tuples, and lists, regardless of what is in scope. In a similar way, the prefix type constructors (->), [], (), (,), and so on, always denote the built-in type constructors; they cannot be qualified, nor mentioned in import or export lists (ChapterΒ 5). (Hence the special production, βgtyconβ, above.)
Although the list and tuple types have special syntax, their semantics is the same as the equivalent user-defined algebraic data types.
Notice that expressions and types have a consistent syntax. If (\ e1 -> e2), [e1], and (t1 -> t2), [t1], and (t1, t2), respectively.
With one exception (that of the distinguished type variable in a class declaration (SectionΒ 4.3.1)), the type variables in a Haskell type expression are all assumed to be universally quantified; there is no explicit syntax for universal quantification [5]. For example, the type expression a -> a denotes the type
4.1.3 Syntax of Class Assertions and Contexts
A class assertion has form
where =>.
4.1.4 Semantics of Types and Classes
In this section, we provide informal details of the type system. (Wadler and Blott [7] and Jones [6] discuss type and constructor classes, respectively, in more detail.)
The Haskell type system attributes a type to each expression in the program. In general, a type is of the form
Eq a => a -> a
(Eq a, Show a, Eq b) => [a] -> [b] -> String
(Eq (f a), Functor f) => (a -> b) -> f a -> f b -> BoolIn the third type, the constraint Eq (f a) cannot be made simpler because f is universally quantified.
The type of an expression instance declaration or a deriving clause).
Types are related by a generalization preorder (specified below); the most general type, up to the equivalence induced by the generalization preorder, that can be assigned to a particular expression (in a given environment) is called its principal type. Haskellβs extended Hindley-Milner type system can infer the principal type of all expressions, including the proper use of overloaded class methods (although certain ambiguous overloadings could arise, as described in SectionΒ 4.3.4). Therefore, explicit typings (called type signatures) are usually optional (see SectionΒ 3.16 and SectionΒ 4.4.1).
The type
is identical toπ‘ 2 .π ( π‘ 1 ) - Whenever
holds in the class environment,ππ₯ 2 also holds.π ( ππ₯ 1 )
A value of type double:
double x = x + xThe most general type of double is double may be applied to values of type Int (instantiating Int), since Num Int holds, because Int is an instance of the class Num. However, double may not normally be applied to values of type Char, because Char is not normally an instance of class Num. The user may choose to declare such an instance, in which case double may indeed be applied to a Char.
4.2 User-Defined Datatypes
In this section, we describe algebraic datatypes (data declarations), renamed datatypes (newtype declarations), and type synonyms (type declarations). These declarations may only appear at the top level of a module.
4.2.1 Algebraic Datatype Declarations
The precedence for a : Foo a parses as a : (Foo a)).
An algebraic datatype declaration has the form:
where
The types of the data constructors are given by:
where
For example, the declaration
data Eq a => Set a = NilSet | ConsSet a (Set a)introduces a type constructor Set of kind NilSet and ConsSet with types
NilSet | :: | |
ConsSet | :: |
In the example given, the overloaded type for ConsSet ensures that ConsSet can only be applied to values whose type is an instance of the class Eq. Pattern matching against ConsSet also gives rise to an Eq a constraint. For example:
f (ConsSet a s) = athe function f has inferred type Eq a => Set a -> a. The context in the data declaration has no other effect whatsoever.
The visibility of a datatypeβs constructors (i.e.Β the βabstractnessβ of the datatype) outside of the module in which the datatype is defined is controlled by the form of the datatypeβs name in the export list as described in SectionΒ 5.8.
The optional deriving part of a data declaration has to do with derived instances, and is described in SectionΒ 4.3.3.
Labelled Fields A data constructor of arity
A constructor definition in a data declaration may assign labels to the fields of the constructor, using the record syntax (
data C = F { f1,f2 :: Int, f3 :: Bool }defines a type and constructor identical to the one produced by
data C = F Int Int BoolOperations using field labels are described in SectionΒ 3.15. A data declaration may use the same field label in multiple constructors as long as the typing of the field is the same in all cases after type synonym expansion. A label cannot be shared by more than one type in scope. Field names share the top level namespace with ordinary variables and class methods and must not conflict with other top level names in scope.
The pattern F { } matches any value built with constructor F, whether or not F was declared with record syntax.
Strictness Flags Whenever a data constructor is applied, each argument to the constructor is evaluated if and only if the corresponding type in the algebraic datatype declaration has a strictness flag, denoted by an exclamation point, β!β. Lexically, β!β is an ordinary varsym not a
Translation: A declaration of the form
where each
where $ if $! (see SectionΒ 6.2) if
4.2.2 Type Synonym Declarations
A type synonym declaration introduces a new type that is equivalent to an old type. It has the form
which introduces a new type constructor,
type List = []Type constructor symbols
Although recursive and mutually recursive datatypes are allowed, this is not so for type synonyms, unless an algebraic datatype intervenes. For example,
type Rec a = [Circ a]
data Circ a = Tag [Rec a]is allowed, whereas
type Rec a = [Circ a] -- invalid
type Circ a = [Rec a] -- invalidis not. Similarly, type Rec a = [Rec a] is not allowed.
Type synonyms are a convenient, but strictly syntactic, mechanism to make type signatures more readable. A synonym and its definition are completely interchangeable, except in the instance type of an instance declaration (SectionΒ 4.3.2).
4.2.3 Datatype Renamings
A declaration of the form
introduces a new type whose representation is the same as an existing type. The type newtype may be used to define recursive types. The constructor t to type newtype does not change the underlying representation of an object.
New instances (see SectionΒ 4.3.2) can be defined for a type defined by newtype but may not be defined for a type synonym. A type created by newtype differs from an algebraic datatype in that the representation of an algebraic datatype has an extra level of indirection. This difference may make access to the representation less efficient. The difference is reflected in different rules for pattern matching (see SectionΒ 3.17). Unlike algebraic datatypes, the newtype constructor
The following examples clarify the differences between data (algebraic datatypes), type (type synonyms), and newtype (renaming types.) Given the declarations
data D1 = D1 Int
data D2 = D2 !Int
type S = Int
newtype N = N Int
d1 (D1 i) = 42
d2 (D2 i) = 42
s i = 42
n (N i) = 42the expressions 42. In particular,
The optional deriving part of a deriving declaration is treated in the same way as the deriving component of a data declaration; see SectionΒ 4.3.3.
A newtype declaration may use field-naming syntax, though of course there may only be one field. Thus:
newtype Age = Age { unAge :: Int }brings into scope both a constructor and a de-constructor:
Age :: Int -> Age
unAge :: Age -> Int4.3 Type Classes and Overloading
4.3.1 Class Declarations
A class declaration introduces a new class and the operations (class methods) on it. A class declaration has the general form:
This introduces a new class name
The superclass relation must not be cyclic; i.e.Β it must form a directed acyclic graph.
The class declaration contains three kinds of declarations:
The class declaration introduces new class methods
, whose scope extends outside theπ£ π classdeclaration. The class methods of a class declaration are precisely the mbox{ } for which there is an explicit type signatureπ π‘ π£ π π£ π :: ππ₯ π => π‘ π in
. Class methods share the top level namespace with variable bindings and field names; they must not conflict with other top level bindings in scope. That is, a class method can not have the same name as a top level definition, a field name, or another class method.ππππππ The type of the top-level class method
is:π£ π π£ π :: β π’ , π€ _ . ( πΆ π’ , ππ₯ π ) => π‘ π The
must mentionπ‘ π ; it may mention type variablesπ’ other thanπ€ _ , in which case the type ofπ’ is polymorphic in bothπ£ π andπ’ . Theπ€ _ may constrain onlyππ₯ π ; in particular, theπ€ _ may not constrainππ₯ π . For example:π’ class Foo a where op :: Num b => a -> b -> aHere the type of
opis .β π , π . ( π΅ππ π , π½ππ π ) β π β π β π - The
may also contain a fixity declaration for any of the class methods (but for no other values). However, since class methods declare top-level values, the fixity declaration for a class method may alternatively appear at top level, outside the class declaration.ππππππ Lastly, the
may contain a default class method for any of theππππππ . The default class method forπ£ π is used if no binding for it is given in a particularπ£ π instancedeclaration (see SectionΒ 4.3.2). The default method declaration is a normal value definition, except that the left hand side may only be a variable or function definition. For example:class Foo a where op1, op2 :: a -> a (op1, op2) = ...is not permitted, because the left hand side of the default declaration is a pattern.
Other than these cases, no other declarations are permitted in
A class declaration with no where part may be useful for combining a collection of classes into a larger one that inherits all of the class methods in the original ones. For example:
class (Read a, Show a) => Textual aIn such a case, if a type is an instance of all superclasses, it is not automatically an instance of the subclass, even though the subclass has no immediate class methods. The instance declaration must be given explicitly with no where part.
4.3.2 Instance Declarations
| ( | |||
| ( | |||
| ( | |||
| (empty) |
An instance declaration introduces an instance of a class. Let
be a class declaration. The general form of the corresponding instance declaration is:
where
This prohibits instance declarations such as:
instance C (a,a) where ...
instance C (Int,a) where ...
instance C [[a]] where ...The declarations range is in scope only with the qualified name Data.Ix.range.
module A where
import qualified Data.Ix
instance Data.Ix.Ix T where
range = ...The declarations may not contain any type signatures or fixity declarations, since these have already been given in the class declaration. As in the case of default class methods (SectionΒ 4.3.1), the method declarations must take the form of a variable or function definition.
If no binding is given for some class method then the corresponding default class method in the class declaration is used (if present); if such a default does not exist then the class method of this instance is bound to undefined and no compile-time error results.
An instance declaration that makes the type
A type may not be declared as an instance of a particular class more than once in the program.
The class and type must have the same kind; this can be determined using kind inference as described in SectionΒ 4.6.
Assume that the type variables in the instance type
satisfy the constraints in the instance context( π π’ 1 β¦ π’ π ) . Under this assumption, the following two conditions must also be satisfied:ππ₯ β² - The constraints expressed by the superclass context
ofππ₯ [ ( π π’ 1 β¦ π’ π ) / π’ ] must be satisfied. In other words,πΆ must be an instance of each ofπ βs superclasses and the contexts of all superclass instances must be implied byπΆ .ππ₯ β² - Any constraints on the type variables in the instance type that are required for the class method declarations in
to be well-typed must also be satisfied.π
In fact, except in pathological cases it is possible to infer from the instance declaration the most general instance context
satisfying the above two constraints, but it is nevertheless mandatory to write an explicit instance context.ππ₯ β² - The constraints expressed by the superclass context
The following example illustrates the restrictions imposed by superclass instances:
class Foo a => Bar a where ...
instance (Eq a, Show a) => Foo [a] where ...
instance Num a => Bar [a] where ...This example is valid Haskell. Since Foo is a superclass of Bar, the second instance declaration is only valid if [a] is an instance of Foo under the assumption Num a. The first instance declaration does indeed say that [a] is an instance of Foo under this assumption, because Eq and Show are superclasses of Num.
If the two instance declarations instead read like this:
instance Num a => Foo [a] where ...
instance (Eq a, Show a) => Bar [a] where ...then the program would be invalid. The second instance declaration is valid only if [a] is an instance of Foo under the assumptions (Eq a, Show a). But this does not hold, since [a] is only an instance of Foo under the stronger assumption Num a.
Further examples of instance declarations may be found in ChapterΒ 9.
4.3.3 Derived Instances
As mentioned in SectionΒ 4.2.1, data and newtype declarations contain an optional deriving form. If the form is included, then derived instance declarations are automatically generated for the datatype in each of the named classes. These instances are subject to the same restrictions as user-defined instances. When deriving a class instance declaration or by including the superclass in the deriving clause.
Derived instances provide convenient commonly-used operations for user-defined datatypes. For example, derived instances for datatypes in the class Eq define the operations == and /=, freeing the programmer from the need to define them.
The only classes in the Prelude for which derived instances are allowed are Eq, Ord, Enum, Bounded, Show, and Read, all mentioned in FigureΒ 3. The precise details of how the derived instances are generated for each of these classes are provided in ChapterΒ 11, including a specification of when such derived instances are possible. Classes defined by the standard libraries may also be derivable.
A static error results if it is not possible to derive an instance declaration over a class named in a deriving form. For example, not all datatypes can properly support class methods in Enum. It is also a static error to give an explicit instance declaration for a class that is also derived.
If the deriving form is omitted from a data or newtype declaration, then no instance declarations are derived for that datatype; that is, omitting a deriving form is equivalent to including an empty deriving form: deriving ().
4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations
A problem inherent with Haskell-style overloading is the possibility of an ambiguous type. For example, using the read and show functions defined in ChapterΒ 11, and supposing that just Int and Bool are members of Read and Show, then the expression
let x = read "..." in show x -- invalidis ambiguous, because the types for show and read,
could be satisfied by instantiating a as either Int in both cases, or Bool. Such expressions are considered ill-typed, a static error.
We say that an expression e has an ambiguous type if, in its type
For example, the earlier expression involving show and read has an ambiguous type since its type is
Ambiguous types can only be circumvented by input from the user. One way is through the use of expression type-signatures as described in SectionΒ 3.16. For example, for the ambiguous expression given earlier, one could write:
let x = read "..." in show (x::Bool)which disambiguates the type.
Occasionally, an otherwise ambiguous expression needs to be made the same type as some variable, rather than being given a fixed type with an expression type-signature. This is the purpose of the function asTypeOf (ChapterΒ 9): x `asTypeOf` y has the value of
approxSqrt x = encodeFloat 1 (exponent x `div` 2) `asTypeOf` x(See SectionΒ 6.4.6 for a description of encodeFloat and exponent.)
Ambiguities in the class Num are most common, so Haskell provides another way to resolve themβwith a default declaration:
where
appears only in constraints of the formπ£ , whereπΆ π£ is a class, andπΆ - at least one of these classes is a numeric class, (that is,
Numor a subclass ofNum), and - all of these classes are defined in the Prelude or a standard library (ListingΒ 4 β ListingΒ 5 show the numeric classes, and FigureΒ 3 shows the classes defined in the Prelude.)
Each defaultable variable is replaced by the first type in the default list that is an instance of all the ambiguous variableβs classes. It is a static error if no such type is found.
Only one default declaration is permitted per module, and its effect is limited to that module. If no default declaration is given in a module then it assumed to be:
default (Integer, Double)The empty default declaration, default (), turns off all defaults in a module.
4.4 Nested Declarations
The following declarations may be used in any declaration list, including the top level of a module.
4.4.1 Type Signatures
A type signature specifies types for variables, possibly with respect to a context. A type signature has the form:
which is equivalent to asserting
As mentioned in SectionΒ 4.1.2, every type variable appearing in a signature is universally quantified over that signature, and hence the scope of a type variable is limited to the type signature that contains it. For example, in the following declarations
f :: a -> a
f x = x :: a -- invalidthe aβs in the two type signatures are quite distinct. Indeed, these declarations contain a static error, since x does not have type x is dependent on the type of f; there is currently no way in Haskell to specify a signature for a variable with a dependent type; this is explained in SectionΒ 4.5.4.)
If a given program includes a signature for a variable
If a variable
For example, if we define
sqr x = x*xthen the principal type is sqr 5 or sqr 0.1. It is also valid to declare a more specific type, such as
sqr :: Int -> Intbut now applications such as sqr 0.1 are invalid. Type signatures such as
sqr :: (Num a, Num b) => a -> b -- invalid
sqr :: a -> a -- invalidare invalid, as they are more general than the principal type of sqr.
Type signatures can also be used to support polymorphic recursion. The following definition is pathological, but illustrates how a type signature can be used to specify a type more general than the one that would be inferred:
data T a = K (T Int) (T a)
f :: T a -> a
f (K x y) = if f x == 1 then f y else undefinedIf we remove the signature declaration, the type of f will be inferred as T Int -> Int due to the first recursive call for which the argument to f is T Int. Polymorphic recursion allows the user to supply the more general type signature, T a -> a.
4.4.2 Fixity Declarations
A fixity declaration gives the fixity and binding precedence of one or more operators. The
There are three kinds of fixity, non-, left- and right-associativity (infix, infixl, and infixr, respectively), and ten precedence levels, 0 to 9 inclusive (level 0 binds least tightly, and level 9 binds most tightly). If the infixl 9 (See ChapterΒ 3 for more on the use of fixities). TableΒ 1 lists the fixities and precedences of the operators defined in the Prelude.
| Precedence | Left associative operators | Non-associative operators | Right associative operators |
|---|---|---|---|
| 9 | !! | . | |
| 8 | ^,^^,** | ||
| 7 | *, /, div, mod, rem, quot | ||
| 6 | +,- | ||
| 5 | :,++ | ||
| 4 | ==, /=, <,<=, >, >=, elem, notElem | ||
| 3 | && | ||
| 2 | || | ||
| 1 | >>, >>= | ||
| 0 | $, $!, seq |
Fixity is a property of a particular entity (constructor or variable), just like its type; fixity is not a property of that entityβs name. For example:
module Bar( op ) where
infixr 7 `op`
op = ...
module Foo where
import qualified Bar
infix 3 `op`
a `op` b = (a `Bar.op` b) + 1
f x = let
p `op` q = (p `Foo.op` q) * 2
in ...Here, `Bar.op` is infixr 7, `Foo.op` is infix 3, and the nested definition of op in fβs right-hand side has the default fixity of infixl 9. (It would also be possible to give a fixity to the nested definition of `op` with a nested fixity declaration.)
4.4.3 Function and Pattern Bindings
| (pattern guard) | |||
| (local declaration) | |||
| (boolean guard) |
We distinguish two cases within this syntax: a pattern binding occurs when the left hand side is a where or let construct.
4.4.3.1 Function bindings
A function binding binds a variable to a function value. The general form of a function binding for variable
where each
or
and where
Note that all clauses defining a function must be contiguous, and the number of patterns in each clause must be the same. The set of patterns corresponding to each match must be linearβno variable is allowed to appear more than once in the entire set.
Alternative syntax is provided for binding functional values to infix operators. For example, these three function definitions are all equivalent:
plus x y z = x+y+z
x `plus` y = \ z -> x+y+z
(x `plus` y) z = x+y+zNote that fixity resolution applies to the infix variants of the function binding in the same way as for expressions (SectionΒ 10.6). Applying fixity resolution to the left side of the equals in a function binding must leave the ## with precedence 6, then this definition would be illegal:
a ## b : xs = expbecause : has precedence 5, so the left hand side resolves to (a ## x) : xs, and this cannot be a pattern binding because (a ## x) is not a valid pattern.
Translation: The general binding form for functions is semantically equivalent to the equation (i.e. simple pattern binding):
where the
4.4.3.2 Pattern bindings
A pattern binding binds variables to values. A simple pattern binding has form ~ in front of it. See the translation in Section SectionΒ 3.12.
The general form of a pattern binding is
Translation: The pattern binding above is semantically equivalent to this simple pattern binding:
4.5 Static Semantics of Function and Pattern Bindings
The static semantics of the function and pattern bindings of a let expression or where clause are discussed in this section.
4.5.1 Dependency Analysis
In general the static semantics are given by applying the normal Hindley-Milner inference rules. In order to increase polymorphism, these rules are applied to groups of bindings identified by a dependency analysis.
A binding
contains a free identifier that has no type signature and is bound byπ 1 , orπ 2 depends on a binding that depends onπ 1 .π 2
A declaration group is a minimal set of mutually dependent bindings. Hindley-Milner type inference is applied to each declaration group in dependency order. The order of declarations in where/let constructs is irrelevant.
4.5.2 Generalization
The Hindley-Milner type system assigns types to a let-expression in two stages:
- The declaration groups are considered in dependency order. For each group, a type with no universal quantification is inferred for each variable bound in the group. Then, all type variables that occur in these types are universally quantified unless they are associated with bound variables in the type environment; this is called generalization.
- Finally, the body of the let-expression is typed.
For example, consider the declaration
f x = let g y = (y,y)
in ...The type of gβs definition is g the polymorphic type ...β part can proceed.
When typing overloaded definitions, all the overloading constraints from a single declaration group are collected together, to form the context for the type of each variable declared in the group. For example, in the definition:
f x = let g1 x y = if x>y then show x else g2 y x
g2 p q = g1 q p
in ...The types of the definitions of g1 and g2 are both >), and show). The type variables appearing in this collection of constraints are called the constrained type variables.
The generalization step attributes to both g1 and g2 the type
Notice that g2 is overloaded in the same way as g1 even though the occurrences of > and show are in the definition of g1.
If the programmer supplies explicit type signatures for more than one variable in a declaration group, the contexts of these signatures must be identical up to renaming of the type variables.
4.5.3 Context Reduction Errors
As mentioned in SectionΒ 4.1.4, the context of a type may constrain only a type variable, or the application of a type variable to one or more types. Hence, types produced by generalization must be expressed in a form in which all context constraints have be reduced to this βhead normal formβ. Consider, for example, the definition:
f xs y = xs == [y]Its type is given by
f :: Eq a => [a] -> a -> Booland not
f :: Eq [a] => [a] -> a -> BoolEven though the equality is taken at the list type, the context must be simplified, using the instance declaration for Eq on lists, before generalization. If no such instance is in scope, a static error occurs.
Here is an example that shows the need for a constraint of the form
f :: (Monad m, Eq (m a)) => a -> m a -> Bool
f x y = return x == yThe type of return is Monad m => a -> m a; the type of (==) is Eq a => a -> a -> Bool. The type of f should be therefore (Monad m, Eq (m a)) => a -> m a -> Bool, and the context cannot be simplified further.
The instance declaration derived from a data type deriving clause (see SectionΒ 4.3.3) must, like any instance declaration, have a simple context; that is, all the constraints must be of the form
data Apply a b = App (a b) deriving Showthe derived Show instance will produce a context Show (a b), which cannot be reduced and is not simple; thus a static error results.
4.5.4 Monomorphism
Sometimes it is not possible to generalize over all the type variables used in the type of the definition. For example, consider the declaration
f x = let g y z = ([x,y], z)
in ...In an environment where x has type gβs definition is g is monomorphic in the type variable
The effect of such monomorphism is that the first argument of all applications of g must be of a single type. For example, it would be valid for the β...β to be
(g True, g False)(which would, incidentally, force x to have type Bool) but invalid for it to be
(g True, g 'c')In general, a type
It is worth noting that the explicit type signatures provided by Haskell are not powerful enough to express types that include monomorphic type variables. For example, we cannot write
f x = let
g :: a -> b -> ([a],b)
g y z = ([x,y], z)
in ...because that would claim that g was polymorphic in both a and b (SectionΒ 4.4.1). In this program, g can only be given a type signature if its first argument is restricted to a type not involving type variables; for example
g :: Int -> b -> ([Int],b)This signature would also cause x to have type Int.
4.5.5 The Monomorphism Restriction
Haskell places certain extra restrictions on the generalization step, beyond the standard Hindley-Milner restriction described above, which further reduces polymorphism in particular cases.
The monomorphism restriction depends on the binding syntax of a variable. Recall that a variable is bound by either a function binding or a pattern binding, and that a simple pattern binding is a pattern binding in which the pattern consists of only a single variable (SectionΒ 4.4.3).
The following two rules define the monomorphism restriction:
The monomorphism restriction
- Rule 1.
We say that a given declaration group is unrestricted if and only if:
- (a)
- every variable in the group is bound by a function binding or a simple pattern binding (SectionΒ 4.4.3.2), and
- (b)
- an explicit type signature is given for every variable in the group that is bound by simple pattern binding.
The usual Hindley-Milner restriction on polymorphism is that only type variables that do not occur free in the environment may be generalized. In addition, the constrained type variables of a restricted declaration group may not be generalized in the generalization step for that group. (Recall that a type variable is constrained if it must belong to some type class; see SectionΒ 4.5.2.)
- Rule 2.
- Any monomorphic type variables that remain when type inference for an entire module is complete, are considered ambiguous, and are resolved to particular types using the defaulting rules (SectionΒ 4.3.4).
Motivation Rule 1 is required for two reasons, both of which are fairly subtle.
Rule 1 prevents computations from being unexpectedly repeated. For example,
genericLengthis a standard function (in libraryData.List) whose type is given bygenericLength :: Num a => [b] -> aNow consider the following expression:
let { len = genericLength xs } in (len, len)It looks as if
lenshould be computed only once, but without Rule 1 it might be computed twice, once at each of two different overloadings. If the programmer does actually wish the computation to be repeated, an explicit type signature may be added:let { len :: Num a => a; len = genericLength xs } in (len, len)Rule 1 prevents ambiguity. For example, consider the declaration group
[(n,s)] = reads tRecall that
readsis a standard function whose type is given by the signaturereads :: (Read a) => String -> [(a,String)]Without RuleΒ 1,
nwould be assigned the type andβ π . ππππ π β π β π sthe type . The latter is an invalid type, because it is inherently ambiguous. It is not possible to determine at what overloading to useβ π . ππππ π β ππππππ s, nor can this be solved by adding a type signature fors. Hence, when non-simple pattern bindings are used (SectionΒ 4.4.3.2), the types inferred are always monomorphic in their constrained type variables, irrespective of whether a type signature is provided. In this case, bothnandsare monomorphic in .π The same constraint applies to pattern-bound functions. For example, in
(f,g) = ((+),(-))both
fandgare monomorphic regardless of any type signatures supplied forforg.
RuleΒ 2 is required because there is no way to enforce monomorphic use of an exported binding, except by performing type inference on modules outside the current module. RuleΒ 2 states that the exact types of all the variables bound in a module must be determined by that module alone, and not by any modules that import it.
module M1(len1) where
default( Int, Double )
len1 = genericLength "Hello"
module M2 where
import M1(len1)
len2 = (2*len1) :: RationalWhen type inference on module M1 is complete, len1 has the monomorphic type Num a => a (by Rule 1). Rule 2 now states that the monomorphic type variable a is ambiguous, and must be resolved using the defaulting rules of SectionΒ 4.3.4. Hence, len1 gets type Int, and its use in len2 is type-incorrect. (If the above code is actually what is wanted, a type signature on len1 would solve the problem.)
This issue does not arise for nested bindings, because their entire scope is visible to the compiler.
Consequences The monomorphism rule has a number of consequences for the programmer. Anything defined with function syntax usually generalizes as a function is expected to. Thus in
f x y = x+ythe function f may be used at any overloading in class Num. There is no danger of recomputation here. However, the same function defined with pattern syntax:
f = \x -> \y -> x+yrequires a type signature if f is to be fully overloaded. Many functions are most naturally defined using simple pattern bindings; the user must be careful to affix these with type signatures to retain full overloading. The standard prelude contains many examples of this:
sum :: (Num a) => [a] -> a
sum = foldl (+) 0 RuleΒ 1 applies to both top-level and nested definitions. Consider
module M where
len1 = genericLength "Hello"
len2 = (2*len1) :: RationalHere, type inference finds that len1 has the monomorphic type (Num a => a); and the type variable a is resolved to Rational when performing type inference on len2.
4.6 Kind Inference
This section describes the rules that are used to perform kind inference, i.e. to calculate a suitable kind for each type constructor and class appearing in a given program.
The first step in the kind inference process is to arrange the set of datatype, synonym, and class definitions into dependency groups. This can be achieved in much the same way as the dependency analysis for value declarations that was described in SectionΒ 4.5.1. For example, the following program fragment includes the definition of a datatype constructor D, a synonym S and a class C, all of which would be included in the same dependency group:
data C a => D a = Foo (S a)
type S a = [D a]
class C a where
bar :: a -> D a -> BoolThe kinds of variables, constructors, and classes within each group are determined using standard techniques of type inference and kind-preserving unification [6]. For example, in the definitions above, the parameter a appears as an argument of the function constructor (->) in the type of bar and hence must have kind D and S must have kind C must have kind
It is possible that some parts of an inferred kind may not be fully determined by the corresponding definitions; in such cases, a default of a parameter in each of the following examples:
data App f a = A (f a)
data Tree a = Leaf | Fork (Tree a) (Tree a)This would give kinds App and Tree, respectively, for any kind
Defaults are applied to each dependency group without consideration of the ways in which particular type constructor constants or classes are used in later dependency groups or elsewhere in the program. For example, adding the following definition to those above does not influence the kind inferred for Tree (by changing it to [], Tree:
type FunnyTree = Tree [] -- invalidThis is important because it ensures that each constructor and class are used consistently with the same kind whenever they are in scope.