Changes between Initial Version and Version 1 of CompletePatternPragmaTroubles


Ignore:
Timestamp:
Dec 5, 2017 8:10:19 PM (22 months ago)
Author:
dfeuer
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CompletePatternPragmaTroubles

    v1 v1  
     1A couple issues have arisen with `COMPLETE` pragmas for patterns.
     2
     3=== Type issues
     4
     5#14135 involves a panic when types don't match up correctly. Simon's suggestion in
     6ticket:14135#comment:8 seems to make a lot of sense:
     7
     8> filter the candidate COMPLETE sets, to choose only those all of whose
     9> constructors match the type of the scrutinee.
     10
     11Why does that make sense, and not just ignoring patterns that don't match? Because
     12what remains is likely not complete! Imagine
     13
     14{{{#!hs
     15LZ :: (Ord a, Num a) => () => a -> a
     16Z :: (Eq a, Num a) => () => a -> a
     17GZ :: (Ord a, Num a) => () => a -> a
     18{-# COMPLETE LZ, Z, GZ #-}
     19}}}
     20
     21for splitting numbers by whether they're negative, zero, or positive.
     22If a type isn't `Ord`, then filtering out the matching patterns from
     23this set would give no patterns; but that doesn't mean the type is
     24uninhabited.
     25
     26=== Overlap issues
     27
     28Pattern matches on ''individual constructors'' can't overlap. This is ''not'' the
     29case for general pattern synonyms. This is highlighted by #14253. In particular, the
     30fact that `P1` and `P2` form a `COMPLETE` set does ''not'' mean that other patterns
     31are necessarily redundant. The simplest rule that will do something fairly sensible
     32is this: only consider patterns redundant as a result of a `COMPLETE` pragma if they
     33come after ''all'' the patterns listed in that pragma.
     34
     35If I have
     36
     37{{{#!hs
     38data Foo = Bar | Baz
     39pattern Quux :: Foo
     40pattern Quuux :: Foo
     41{-# COMPLETE Quux, Quuux #-}
     42}}}
     43
     44Then
     45
     46{{{#!hs
     47f Quux = ...
     48f Quuux = ...
     49f Bar = ...
     50}}}
     51
     52should complain that `Bar` is redundant, but
     53
     54{{{#!hs
     55f Quux = ...
     56f Bar = ...
     57f Quuux = ...
     58}}}
     59
     60should pass, because there is no `Quuux` before `Bar`.
     61
     62A fancier approach would be to offer a pragma that allows users to specify
     63a partial ordering of patterns by overlap. This would let GHC catch more
     64redundant matches, but may not be worth the complexity.