summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorCale Gibbard <cgibbard@gmail.com>2021-02-22 15:56:22 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-03-04 23:17:00 -0500
commit4cdf8b5ef923e4b860b2d7e61d034817cb81ddbc (patch)
tree46977b11ae67513e46db96b49cf0e30face75963 /docs
parent1a52c53bb7bc5ef91e251306cf056fcee6a4e15c (diff)
downloadhaskell-4cdf8b5ef923e4b860b2d7e61d034817cb81ddbc.tar.gz
Bring back COMPLETE sets filtered by result TyCon (#14422)
Commit 2a94228 dramatically simplified the implementation and improved the performance of COMPLETE sets while making them applicable in more scenarios at the same time. But it turned out that there was a change in semantics that (to me unexpectedly) broke users' expectations (see #14422): They relied on the "type signature" of a COMPLETE pragma to restrict the scrutinee types of a pattern match for which they are applicable. This patch brings back that filtering, so the semantics is the same as it was in GHC 9.0. See the updated Note [Implementation of COMPLETE pragmas]. There are a few testsuite output changes (`completesig13`, `T14422`) which assert this change. Co-authored-by: Sebastian Graf <sebastian.graf@kit.edu>
Diffstat (limited to 'docs')
-rw-r--r--docs/users_guide/exts/pragmas.rst53
1 files changed, 53 insertions, 0 deletions
diff --git a/docs/users_guide/exts/pragmas.rst b/docs/users_guide/exts/pragmas.rst
index 1f6399fb7b..fd0127f54a 100644
--- a/docs/users_guide/exts/pragmas.rst
+++ b/docs/users_guide/exts/pragmas.rst
@@ -887,6 +887,59 @@ modules. ``COMPLETE`` pragmas should be thought of as asserting a
universal truth about a set of patterns and as a result, should not be
used to silence context specific incomplete match warnings.
+It is also possible to restrict the types to which a ``COMPLETE`` pragma applies
+by putting a double colon ``::`` after the list of constructors, followed by a
+result type constructor, which will be used to restrict the cases in which the
+pragma applies. GHC will compare the annotated result type constructor with the
+type constructor in the head of the scrutinee type in a pattern match to see if
+the ``COMPLETE`` pragma is meant to apply to it.
+
+This is especially useful in cases that the constructors specified are
+polymorphic, e.g.::
+
+ data Proxy a = Proxy
+
+ class IsEmpty a where
+ isEmpty :: a -> Bool
+
+ class IsCons a where
+ type Elt a
+ isCons :: a -> Maybe (Elt a, a)
+
+ pattern Empty :: IsEmpty a => a
+ pattern Empty <- (isEmpty -> True)
+
+ pattern Cons :: IsCons a => Elt a -> a -> a
+ pattern Cons x xs <- (isCons -> Just (x,xs))
+
+ instance IsEmpty (Proxy a) where
+ isEmpty Proxy = True
+
+ instance IsEmpty [a] where
+ isEmpty = null
+
+ instance IsCons [a] where
+ type Elt [a] = a
+ isCons [] = Nothing
+ isCons (x:xs) = Just (x,xs)
+
+ {-# COMPLETE Empty :: Proxy #-}
+ {-# COMPLETE Empty, Cons :: [] #-}
+
+ foo :: Proxy a -> Int
+ foo Empty = 0
+
+ bar :: [a] -> Int
+ bar Empty = 0
+ bar (Cons _ _) = 1
+
+ baz :: [a] -> Int
+ baz Empty = 0
+
+In this example, ``foo`` and ``bar`` will not be warned about, as their
+pattern matches are covered by the two ``COMPLETE`` pragmas above, but
+``baz`` will be warned about as incomplete.
+
.. _overlap-pragma:
``OVERLAPPING``, ``OVERLAPPABLE``, ``OVERLAPS``, and ``INCOHERENT`` pragmas