[GHC] #14293: View patterns with locally defined functions in restructuring don't compile

GHC ghc-devs at haskell.org
Fri Sep 29 09:32:49 UTC 2017


#14293: View patterns with locally defined functions in restructuring don't compile
-------------------------------------+-------------------------------------
        Reporter:  heisenbug         |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:
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 simonpj):

 Here's an even more tricky case:
 {{{
 (foo -> (a,b), foo) = ([True,False], \(a:b:_) -> (a,b))
 }}}
 The lazy pattern binding matches a pair, binding `foo`, which is used as
 the viewing function in another part of the same pattern.

 I think the Right Thing here is to rename the ''binders'' of the pattern
 first, and then later rename the ''occurrences'' of bound variables.  The
 latter occur in view patterns.

 At the moment a `HsBindLR` has two pass parameters, and goes through these
 stages:

 * `HsBindLR Parsed Parsed`: after the parser
 * `HsBindLR` Renamed Parsed`: binders renamed, but RHSs not renamed yet
 * `HsBindLR` Renamed Renamed`: fully renamed

 But patterns have only one pass parameter!  So perhaps we can give them
 two, like `HsBindLR`.

 Then `rnPat` would be split into two,
 * `rnPatLHS` that deals with the binders, and
 * `rnPatRHS` that deals with the expressions in view patterns.

 The latter would be much simpler than the current `rnPat`: just find the
 view patterns and renamed the view function.

 The former is pretty much what we have now in `rnPat`.

 In the case of lambda/case patterns we don't want to split in this way.
 We positively want a left-to-right bias.  For example
 {{{
 f (foo -> (a,b), foo) = ...
 }}}
 is ill-scoped.

 So maybe `rnPatLHS` has type (roughly)
 {{{
 rnPatLHS :: Pat GhcPs GhcPs
          -> (LHsExpr GhcPs -> RnM (LHsExpr p))
          -> (LPat GhcRn p -> RnM (a, FreeVars))
          -> RnM (a, FreeVars)
 }}}
 Here the second argument is used to rename the view functions; either it's
 a no-op (used in bindings) or it's `rnLHsExpr` (use in case/lambda).

 I have not worked through the details but it seems plausible.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/14293#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list