[commit: ghc] master: Document how GHC disambiguates between multiple COMPLETE sets (0e60cc1)
git at git.haskell.org
git at git.haskell.org
Mon Sep 25 19:16:00 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/0e60cc1825aace414597b644731c30269994f7fb/ghc
>---------------------------------------------------------------
commit 0e60cc1825aace414597b644731c30269994f7fb
Author: Ryan Scott <ryan.gl.scott at gmail.com>
Date: Mon Sep 25 14:21:54 2017 -0400
Document how GHC disambiguates between multiple COMPLETE sets
Summary:
Up until now, the knowledge of how GHC chooses which
`COMPLETE` set to use in the presence of multiple applicable
`COMPLETE` sets for a single data type constructor was only
documented in the GHC wiki. But this really should be advertised to
anyone who uses `COMPLETE` pragmas heavily, so per SPJ's advice in
https://ghc.haskell.org/trac/ghc/ticket/14253#comment:10, this adds
this wisdom to the GHC users' guide.
Test Plan: Read it
Reviewers: austin, bgamari
Subscribers: mpickering, rwbarton, thomie
GHC Trac Issues: #14253
Differential Revision: https://phabricator.haskell.org/D4005
>---------------------------------------------------------------
0e60cc1825aace414597b644731c30269994f7fb
compiler/deSugar/Check.hs | 7 ++++++-
docs/users_guide/glasgow_exts.rst | 43 +++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/compiler/deSugar/Check.hs b/compiler/deSugar/Check.hs
index 53b766f..3226a87 100644
--- a/compiler/deSugar/Check.hs
+++ b/compiler/deSugar/Check.hs
@@ -102,7 +102,12 @@ liftD m = ListT $ \sk fk -> m >>= \a -> sk a fk
-- Pick the first match complete covered match or otherwise the "best" match.
-- The best match is the one with the least uncovered clauses, ties broken
-- by the number of inaccessible clauses followed by number of redundant
--- clauses
+-- clauses.
+--
+-- This is specified in the
+-- "Disambiguating between multiple ``COMPLETE`` pragmas" section of the
+-- users' guide. If you update the implementation of this function, make sure
+-- to update that section of the users' guide as well.
getResult :: PmM PmResult -> DsM PmResult
getResult ls = do
res <- fold ls goM (pure Nothing)
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index 65f8629..edfee6c 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -14047,6 +14047,49 @@ the user must provide a type signature. ::
foo :: [a] -> Int
foo T = 5
+.. _multiple-complete-pragmas:
+
+Disambiguating between multiple ``COMPLETE`` pragmas
+----------------------------------------------------
+
+What should happen if there are multiple ``COMPLETE`` sets that apply to a
+single set of patterns? Consider this example: ::
+
+ data T = MkT1 | MkT2 | MkT2Internal
+ {-# COMPLETE MkT1, MkT2 #-}
+ {-# COMPLETE MkT1, MkT2Internal #-}
+
+ f :: T -> Bool
+ f MkT1 = True
+ f MkT2 = False
+
+Which ``COMPLETE`` pragma should be used when checking the coverage of the
+patterns in ``f``? If we pick the ``COMPLETE`` set that covers ``MkT1`` and
+``MkT2``, then ``f`` is exhaustive, but if we pick the other ``COMPLETE`` set
+that covers ``MkT1`` and ``MkT2Internal``, then ``f`` is *not* exhaustive,
+since it fails to match ``MkT2Internal``. An intuitive way to solve this
+dilemma is to recognize that picking the former ``COMPLETE`` set produces the
+fewest number of uncovered pattern clauses, and thus is the better choice.
+
+GHC disambiguates between multiple ``COMPLETE`` sets based on this rationale.
+To make things more formal, when the pattern-match checker requests a set of
+constructors for some data type constructor ``T``, the checker returns:
+
+* The original set of data constructors for ``T``
+* Any ``COMPLETE`` sets of type ``T``
+
+GHC then checks for pattern coverage using each of these sets. If any of these
+sets passes the pattern coverage checker with no warnings, then we are done. If
+each set produces at least one warning, then GHC must pick one of the sets of
+warnings depending on how good the results are. The results are prioritized in
+this order:
+
+1. Fewest uncovered clauses
+2. Fewest redundant clauses
+3. Fewest inaccessible clauses
+4. Whether the match comes from the original set of data constructors or from a
+ ``COMPLETE`` pragma (prioritizing the former over the latter)
+
.. _overlap-pragma:
``OVERLAPPING``, ``OVERLAPPABLE``, ``OVERLAPS``, and ``INCOHERENT`` pragmas
More information about the ghc-commits
mailing list