summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2021-02-19 14:31:38 +0000
committerSimon Peyton Jones <simonpj@microsoft.com>2021-02-25 17:22:56 +0000
commitf19e8e3f1de369ee5feaf1011bb73cad00ff3822 (patch)
treeb533fe5d346981827071a2f2c774968a0915f0d5
parent10e115d39d6062151cc95256fee052b197a46186 (diff)
downloadhaskell-wip/T19396.tar.gz
Update MonoLocalBinds documentationwip/T19396
Update the documentation to specify that MonoLocalBinds is lifted by a partial type signature. This came up in #19396. [skip ci]
-rw-r--r--docs/users_guide/exts/let_generalisation.rst36
-rw-r--r--docs/users_guide/exts/partial_type_signatures.rst3
2 files changed, 28 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 ::
diff --git a/docs/users_guide/exts/partial_type_signatures.rst b/docs/users_guide/exts/partial_type_signatures.rst
index a6a4f73a6a..c2909ed2d0 100644
--- a/docs/users_guide/exts/partial_type_signatures.rst
+++ b/docs/users_guide/exts/partial_type_signatures.rst
@@ -39,6 +39,9 @@ However, because GHC must *infer* the type when part of a type is left
out, it is unable to use polymorphic recursion. The same restriction
takes place when the type signature is omitted completely.
+A partial type signature als makes GHC generalise the binding even if
+:extension:`MonoLocalBinds` is on; see :ref:`mono-local-binds`.
+
.. _pts-syntax:
Syntax