[GHC] #14478: Abstract pattern synonyms (for hsig and hs-boot)
GHC
ghc-devs at haskell.org
Fri Nov 17 08:42:17 UTC 2017
#14478: Abstract pattern synonyms (for hsig and hs-boot)
-------------------------------------+-------------------------------------
Reporter: ezyang | Owner: (none)
Type: feature request | Status: new
Priority: normal | Milestone:
Component: Compiler (Type | Version: 8.2.1
checker) |
Resolution: | Keywords: backpack
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s):
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by ezyang):
OK, so there is a major wrinkle: pattern-synonym signature splitting. The
problem is described in this note:
{{{
Note [The pattern-synonym signature splitting rule]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Given a pattern signature, we must split
the kind-generalised variables, and
the implicitly-bound variables
into universal and existential. The rule is this
(see discussion on Trac #11224):
The universal tyvars are the ones mentioned in
- univ_tvs: the user-specified (forall'd) universals
- req_theta
- res_ty
The existential tyvars are all the rest
For example
pattern P :: () => b -> T a
pattern P x = ...
Here 'a' is universal, and 'b' is existential. But there is a wrinkle:
how do we split the arg_tys from req_ty? Consider
pattern Q :: () => b -> S c -> T a
pattern Q x = ...
This is an odd example because Q has only one syntactic argument, and
so presumably is defined by a view pattern matching a function. But
it can happen (Trac #11977, #12108).
We don't know Q's arity from the pattern signature, so we have to wait
until we see the pattern declaration itself before deciding res_ty is,
and hence which variables are existential and which are universal.
And that in turn is why TcPatSynInfo has a separate field,
patsig_implicit_bndrs, to capture the implicitly bound type variables,
because we don't yet know how to split them up.
It's a slight compromise, because it means we don't really know the
pattern synonym's real signature until we see its declaration. So,
for example, in hs-boot file, we may need to think what to do...
(eg don't have any implicitly-bound variables).
}}}
One way we could manage this without introducing a new syntactic construct
is to have a user specify both pattern synonym signature AND a stub
declaration, literally writing something like:
{{{
pattern P :: () => b -> T a
pattern P x = ...
}}}
That's a literal `...`, because if we introduce this syntax, we now can
also solve the problem of unidirectional versus bidirectional; to declare
only a unidirectional pattern is required, you write:
{{{
pattern P :: () => b -> T a
pattern P x <- ...
}}}
It's annoyingly asymmetric with how we do regular value signatures, but
the alternative seems worse (inventing a new signature syntax which builds
in the arity somehow.)
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14478#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list