[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