Commit feaa31fb authored by Ben Gamari's avatar Ben Gamari Committed by Ben Gamari
Browse files

Remove references to -XRelaxedPolyRec

Test Plan: Read it

Reviewers: dfeuer, austin

Subscribers: thomie

Differential Revision: https://phabricator.haskell.org/D2515

GHC Trac Issues: #11691
parent dcc49044
......@@ -126,6 +126,57 @@ been decided to remove them from the next version of the language
standard. This behaviour can be controlled with the ``DatatypeContexts``
extension. See :ref:`datatype-contexts`.
.. _infelicities-recursive-groups:
Typechecking of recursive binding groups
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Haskell Report specifies that a group of bindings (at top level, or
in a ``let`` or ``where``) should be sorted into strongly-connected
components, and then type-checked in dependency order
(`Haskell Report, Section
4.5.1 <http://www.haskell.org/onlinereport/decls.html#sect4.5.1>`__). As
each group is type-checked, any binders of the group that have an
explicit type signature are put in the type environment with the
specified polymorphic type, and all others are monomorphic until the
group is generalised (`Haskell Report, Section
4.5.2 <http://www.haskell.org/onlinereport/decls.html#sect4.5.2>`__).
Following a suggestion of Mark Jones, in his paper `Typing Haskell in
Haskell <http://citeseer.ist.psu.edu/424440.html>`__, GHC implements a
more general scheme. In GHC *the dependency analysis ignores references to
variables that have an explicit type signature*. As a result of this refined
dependency analysis, the dependency groups are smaller, and more bindings will
typecheck. For example, consider: ::
f :: Eq a => a -> Bool
f x = (x == x) || g True || g "Yes"
g y = (y <= y) || f True
This is rejected by Haskell 98, but under Jones's scheme the definition
for ``g`` is typechecked first, separately from that for ``f``, because
the reference to ``f`` in ``g``\'s right hand side is ignored by the
dependency analysis. Then ``g``\'s type is generalised, to get ::
g :: Ord a => a -> Bool
Now, the definition for ``f`` is typechecked, with this type for ``g``
in the type environment.
The same refined dependency analysis also allows the type signatures of
mutually-recursive functions to have different contexts, something that is
illegal in Haskell 98 (Section 4.5.2, last sentence). GHC only insists that the
type signatures of a *refined* group have identical type signatures; in practice
this means that only variables bound by the same pattern binding must have the
same context. For example, this is fine: ::
f :: Eq a => a -> Bool
f x = (x == x) || g True
g :: Ord a => a -> Bool
g y = (y <= y) || f True
.. _infelicities-Modules:
Module system and interface files
......
......@@ -8412,7 +8412,6 @@ Lexically scoped type variables
.. ghc-flag:: -XScopedTypeVariables
:implies: :ghc-flag:`-XRelaxedPolyRec`
:implies: :ghc-flag:`-XExplicitForAll`
Enable lexical scoping of type variables explicitly introduced with
......@@ -8436,9 +8435,6 @@ signature for ``ys``. In Haskell 98 it is not possible to declare a type
for ``ys``; a major benefit of scoped type variables is that it becomes
possible to do so.
Lexically-scoped type variables are enabled by
:ghc-flag:`-XScopedTypeVariables`. This flag implies :ghc-flag:`-XRelaxedPolyRec`.
Overview
--------
......@@ -8651,64 +8647,6 @@ the Haskell Report) can be completely switched off by
restriction is switched off by default in GHCi's interactive options
(see :ref:`ghci-interactive-options`).
.. _typing-binds:
Generalised typing of mutually recursive bindings
-------------------------------------------------
.. ghc-flag:: -XRelaxedPolyRec
Allow the typechecker to ignore references to bindings with
explicit type signatures.
The Haskell Report specifies that a group of bindings (at top level, or
in a ``let`` or ``where``) should be sorted into strongly-connected
components, and then type-checked in dependency order
(`Haskell Report, Section
4.5.1 <http://www.haskell.org/onlinereport/decls.html#sect4.5.1>`__). As
each group is type-checked, any binders of the group that have an
explicit type signature are put in the type environment with the
specified polymorphic type, and all others are monomorphic until the
group is generalised (`Haskell Report, Section
4.5.2 <http://www.haskell.org/onlinereport/decls.html#sect4.5.2>`__).
Following a suggestion of Mark Jones, in his paper `Typing Haskell in
Haskell <http://citeseer.ist.psu.edu/424440.html>`__, GHC implements a
more general scheme. If :ghc-flag:`-XRelaxedPolyRec` is specified: *the
dependency analysis ignores references to variables that have an
explicit type signature*. As a result of this refined dependency
analysis, the dependency groups are smaller, and more bindings will
typecheck. For example, consider: ::
f :: Eq a => a -> Bool
f x = (x == x) || g True || g "Yes"
g y = (y <= y) || f True
This is rejected by Haskell 98, but under Jones's scheme the definition
for ``g`` is typechecked first, separately from that for ``f``, because
the reference to ``f`` in ``g``\'s right hand side is ignored by the
dependency analysis. Then ``g``\'s type is generalised, to get ::
g :: Ord a => a -> Bool
Now, the definition for ``f`` is typechecked, with this type for ``g``
in the type environment.
The same refined dependency analysis also allows the type signatures of
mutually-recursive functions to have different contexts, something that
is illegal in Haskell 98 (Section 4.5.2, last sentence). With
:ghc-flag:`-XRelaxedPolyRec` GHC only insists that the type signatures of a
*refined* group have identical type signatures; in practice this means
that only variables bound by the same pattern binding must have the same
context. For example, this is fine: ::
f :: Eq a => a -> Bool
f x = (x == x) || g True
g :: Ord a => a -> Bool
g y = (y <= y) || f True
.. _mono-local-binds:
Let-generalisation
......
......@@ -603,14 +603,6 @@ languageOptions =
, flagReverse = "-XNoRecursiveDo"
, flagSince = "6.8.1"
}
, flag { flagName = "-XRelaxedPolyRec"
, flagDescription =
"*(deprecated)* Relaxed checking for :ref:`mutually-recursive "++
"polymorphic functions <typing-binds>`."
, flagType = DynamicFlag
, flagReverse = "-XNoRelaxedPolyRec"
, flagSince = "6.8.1"
}
, flag { flagName = "-XRoleAnnotations"
, flagDescription =
"Enable :ref:`role annotations <role-annotations>`."
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment