> In the case where all the patterns are polymorphic, a user must
> provide a type signature but we accept the definition regardless of
> the type signature they provide. 

Currently we can specify the type *constructor* in a COMPLETE pragma:

pattern J :: a -> Maybe a
pattern J a = Just a

pattern N :: Maybe a
pattern N = Nothing

{-# COMPLETE N, J :: Maybe #-}


Instead if we could specify the type with its free vars, we could refer to them in conlike signatures:

{-# COMPLETE N, [ J :: a -> Maybe a ] :: Maybe a #-}

The COMPLETE pragma for LL could be:

{-# COMPLETE [ LL :: HasSrcSpan a => SrcSpan -> SrcSpanLess a -> a ] :: a #-}

I'm borrowing the list comprehension syntax on purpose because it would allow to define a set of conlikes from a type-list (see my request [1]):

{-# COMPLETE [ V :: (c :< cs) => c -> Variant cs
             | c <- cs
             ] :: Variant cs
  #-}
> 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 > > Note the use of the phrase *type constructor*. The return type of all > constructor-like things in a COMPLETE set must all be headed by the > same type constructor T. Since `LL`'s return type is simply a type > variable `a`, this simply doesn't work with the design of COMPLETE > sets.

Could we use a mechanism similar to instance resolution (with FlexibleInstances) for the checker to return matching COMPLETE sets instead?


--Sylvain


[1] https://mail.haskell.org/pipermail/ghc-devs/2018-July/016053.html