6.11.3. Named default
declarations¶
- NamedDefaults¶
Haskell 2010 language report
includes rarely used default
declarations. Their primary purpose is to
improve the ergonomics of numeric literals in simple programs:
main = print (6 * 7)
The type of the right-hand side of this equation is (Num a, Show a) => IO
()
. There is nothing to tell the compiler which concrete type to instantiate
for a
. To resolve this ambiguity, the user can declare something like
default (Integer, Int, Double)
to specify that any ambiguous type variable (such as a
in the above example)
constrained to class Num
should default to Integer
. If that type doesn’t
satisfy the remaining constraints required from the context (such as Show a
above), the other specified types (e.g. Int
and Double
) are tried in
turn.
The language report applies the default
declarations only to the ambiguities
involving the Num
class. The reason for this limitation is that the numeric
literals are the only literals with ambiguous types in the language
report. Since then, however, the OverloadedStrings
and
OverloadedLists
language extensions have made more syntactic
constructs ambiguous. The former in particular is commonly used for more
convenient coding of Text
literals. Another potential source of ambiguity
are the Prelude and the core libraries which are slowly evolving to be more
generalized.
6.11.3.1. Specifying the class¶
The Haskell 2010 language report specifies the following syntax for the default declaration:
default
(qtycon1 , … , qtyconn) (n ≥ 0)where each type qtyconi must be an instance of class Num
.
With the NamedDefaults
language extension, GHC generalizes these
declarations so the user can specify the default types for any class rather than
just Num
:
default
qtycls? (qtycon1 , … , qtyconn) (n ≥ 0)where each type qtyconi must be an instance of the specified class qtycls. The types may belong to any kind, but the class must have a single parameter. This declaration for example becomes legal:
default Monoid ([Int])
and in turn allows this program to compile:
main = print mempty
If no class is specified, the earlier default of Num
is assumed. In other
words, the Haskell ‘98 syntax of:
default (Int, Float)
would mean exactly the same as:
default Num (Int, Float)
6.11.3.2. Exporting the defaults¶
A default
declaration by itself applies only within the module it’s in. The
NamedDefaults
extension also extends the syntax of module exports
to permit a new form of export item:
module MyModule (default Monoid)
which exports the default that’s in effect in the module for the named class. This can mean either that it’s declared in the same module or that it’s imported from another module.
When exporting a default Num
declaration, the class Num
has to be
explicitly named like any other class.
A module with no explicit export list (as in module M where {...}
) exports
all defaults declared in the module. Re-export of a whole imported module (as in
module M (module N) where{...}
) does not export any defaults.
While default exports must be made explicit, their imports are automatic
and implicit. To suppress or modify an imported default, a module can declare
its own; a local default
declaration will override all imported defaults for
the same class.
6.11.3.3. Definition of subsumption¶
Given two default
declarations for the same class
default
C (Type1a , … , Typema)default
C (Type1b , … , Typenb)
if m ≤ n and the first type sequence Type1a , … , Typema is a sub-sequence of the second sequence Type1b , … , Typenb (i.e., the former can be obtained by removing a number of Typeib items from the latter), we say that the second declaration subsumes the first one.
6.11.3.4. Rules for disambiguation of multiple declarations¶
Only a single default
declaration can be in effect in any single module for
any particular class. If there is more than one default
declaration in
scope, the conflict is resolved using the following rules:
Two declarations for two different classes are not considered to be in conflict; they can, however, clash at a particular use site as we’ll see in the following section.
Two declarations for the same class explicitly declared in the same module are considered a static error.
A
default
declaration in a module takes precedence over any importeddefault
declarations for the same class. However the compiler may issue a warning (enabled by-Wtype-defaults
) if an imported declaration is not subsumed by the local declaration.For any two imported
default
declarations for the same class where one subsumes the other, we ignore the subsumed declaration.If a class has neither a local
default
declaration nor an importeddefault
declaration that subsumes all other importeddefault
declarations for the class, the conflict between the imports is unresolvable. The effect is to ignore alldefault
declarations for the class, so that no declaration is in effect in the module. The compiler may emit a warning in this case, if enabled by-Wtype-defaults
, but no error would be triggered about the imports. Of course an error may be triggered in the body of the module if it contains an actual ambiguous type for the class with the conflicting imported defaults, as per the following subsection.
As a result, in any module each class has either one default declaration in scope (a locally-declared one, or an imported one that subsumes all other imported ones), or none. This single default is used to resolve ambiguity, as described in the next subsection.
Note that a default
declaration that repeats a type name more than once is
perfectly valid, and sometimes may be necessary to resolve coflicts. For
example, a module that imports two conflicting defaults
default C (Int, Bool)
and
default C (Bool, Int)
may use a local declaration
default C (Int, Bool, Int)
to override the imports. Because this declaration subsumes both imported
defaults it will not trigger any compiler warning. When used to resolve
ambiguity (next section) it behaves exactly like default C( Int, Bool)
; that
is, the repeats can be discarded.
6.11.3.5. Rules for disambiguation at the use site¶
The disambiguation rules are a conservative extension of the existing rules in Haskell 2010, which state that ambiguous type variable v is defaultable if:
v appears only in constraints of the form C v, where C is a class, and
at least one of these classes is a numeric class, (that is,
Num
or a subclass ofNum
), andall of these classes are defined in the Prelude or a standard library.
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.
The new rules instead require only that
v appears in at least one constraint of the form C v, where C is a single-parameter class.
Informally speaking, the type selected for defaulting is the first type from the
default
list for class C that satisfies all constraints on type variable
v. If there are multiple Ci v constraints with competing
default
declarations, they have to resolve to the same type.
To make the design more explicit, the following algorithm can be used for default resolution, but any other method that achieves the same effect can be substitued:
Let S be the complete set of unsolved constraints, and initialize Sx to an empty set of constraints. For every v that is free in S:
Define Cv = { Ci v | Ci v ∈ S }, the subset of S consisting of all constraints in S of form (Ci v), where Ci is a single-parameter type class.
Define Dv, by extending Cv with the superclasses of every Ci in Cv
Define Ev, by filtering Dv to contain only classes with a default declaration.
For each Ci in Ev, find the first type T in the default list for Ci for which, for every (Ci v) in Cv, the constraint (Ci T) is soluble.
If there is precisely one type T in the resulting type set, resolve the ambiguity by adding a
v ~ T
i constraint to a set Sx; otherwise report a static error.