summaryrefslogtreecommitdiff
path: root/docs/users_guide/exts/let_generalisation.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide/exts/let_generalisation.rst')
-rw-r--r--docs/users_guide/exts/let_generalisation.rst36
1 files changed, 25 insertions, 11 deletions
diff --git a/docs/users_guide/exts/let_generalisation.rst b/docs/users_guide/exts/let_generalisation.rst
index 07e0c6d43c..d966579377 100644
--- a/docs/users_guide/exts/let_generalisation.rst
+++ b/docs/users_guide/exts/let_generalisation.rst
@@ -16,24 +16,38 @@ An ML-style language usually generalises the type of any ``let``\-bound or
extension :extension:`MonoLocalBinds` GHC implements a slightly more conservative
policy, using the following rules:
-- A variable is *closed* if and only if
+- A *binding group* is a strongly-connected component in the graph in which the nodes are let-bindings,
+ and there is an edge from a let-binding B to the binding for each of the free variables in B's RHS.
+ Before computing the strongly-connected components, any dependencies from variables with
+ complete type signatures are removed.
- - the variable is let-bound
+- With :extension:`MonoLocalBinds`, a binding group is *generalised* if and only if
- - one of the following holds:
+ - Each of its free variables (excluding the variables bound by the group itself)
+ is either *imported* or *closed* (see next bullet), or
- - the variable has an explicit type signature that has no free
- type variables, or
+ - Any of its binders has a partial type signature (see :ref:`partial-type-signatures`).
+ Adding a partial type signature ``f :: _``, (or, more generally, ``f :: _ => _``)
+ provides a per-binding way to ask GHC to
+ perform let-generalisation, even though :extension:`MonoLocalBinds` is on.
- - its binding group is fully generalised (see next bullet)
+ NB: even if the binding is generalised, it may still be affected by the
+ monomorphism restriction, which reduces generalisation
+ (`Haskell Report, Section 4.5.5 <http://www.haskell.org/onlinereport/decls.html#sect4.5.5>`__)
+
+- A variable is *closed* if and only if
+
+ - the variable is let-bound, and
+
+ - one of the following holds:
-- A binding group is *fully generalised* if and only if
+ - the variable has an explicit, complete (i.e. not partial) type signature
+ that has no free type variables, or
- - each of its free variables is either imported or closed, and
+ - its binding group is fully generalised, so it has a closed type
- - the binding is not affected by the monomorphism restriction
- (`Haskell Report, Section
- 4.5.5 <http://www.haskell.org/onlinereport/decls.html#sect4.5.5>`__)
+ Note that a signature like ``f :: a -> a`` is equivalent to ``f :: forall a. a->a``,
+ assuming ``a`` is not in scope, and hence is closed.
For example, consider ::