diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2021-02-19 14:31:38 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-02-26 16:25:02 -0500 |
commit | 29e7f318209794206033065cdc0874a5afe0ad47 (patch) | |
tree | dfb2db71c90c4d4d6942db3e4a7599703aebed74 | |
parent | 98cb9402cf197262f28ea4a7fd7beca9089d53c0 (diff) | |
download | haskell-29e7f318209794206033065cdc0874a5afe0ad47.tar.gz |
Update MonoLocalBinds documentation
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.rst | 36 | ||||
-rw-r--r-- | docs/users_guide/exts/partial_type_signatures.rst | 3 |
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 |