[GHC] #4061: Implement mutually recursive view patterns

GHC cvs-ghc at haskell.org
Tue May 25 05:53:32 EDT 2010


#4061: Implement mutually recursive view patterns
---------------------------------+------------------------------------------
    Reporter:  batterseapower    |        Owner:              
        Type:  feature request   |       Status:  new         
    Priority:  normal            |    Milestone:              
   Component:  Compiler          |      Version:  6.13        
    Keywords:                    |   Difficulty:              
          Os:  Unknown/Multiple  |     Testcase:              
Architecture:  Unknown/Multiple  |      Failure:  None/Unknown
---------------------------------+------------------------------------------

Comment(by simonpj):

 Thinking about it some more, I'm a bit dubious.  You are proposing:
   * In a letrec, bring all the bound variables into scope before checking
 the patterns
 But consider
 {{{
 (f -> Just x, Just f) = e
 }}}
 This is disallowed at the moment (by the left-to-right rule), but your
 rule would allow it.  But the dynamic semantics of pattern matching is
 supposed to be left-to-right, and we literally ''can't'' match the first
 view pattern until we've matched the `(Just f)` pattern.  So I don't think
 we want 'f' to be in scope in the whole pattern.

 If instead we'd had
 {{{
 ( ~(f -> Just x), Just f ) = e
 }}}
 then the dynamic semantics would be ok, because the first (lazy) pattern
 always matches, which allows us to get to the second and thereby bind `f`.
 But I don't think we want lexical scope to depend on lazy patterns!

 Now suppose we had
 {{{
 (f -> Just x) = e1
 Just f = e2
 }}}
 You'd allow that too, and more reasonably, because the patterns are
 evaluated on demand.  But it's hard to think of a rule that makes sense
 here.  We can hardly say "the variables bound by `p=e` are in scope in
 'e', and throughout all definitions in the group, but not in 'p' itself".

 I suppose a compromise might be to extend the left-to-right rule to give a
 top-to-bottom scoping:
   * In a binding `p=e`, the pattern `p` may mention variables bound in
 syntactically earlier bindings in the same binding group (as well as
 variables bound earlier still).  Or, to put it another way, the variables
 bound by a definition scope over the patterns of ''syntactically later''
 pattern bindings in the same let/where group.

 Then we'd have
 {{{
 -- Allowed
 Just f = ...x...
 (f -> Just x) = e1

 -- Not allowed
 (f -> Just x) = e1
 Just f = ...x...
 }}}
 It seems a little ad hoc, and I'm unsure whether it's worth it.

 I suppose it would be more in the order-independent spirit of Haskell to
 say that the compiler should try to sort the definitions into an order
 that allows the above rule to work, so both of the above would be allowed,
 but somthing mutually recursive would not, such as
 {{{
 -- Disallowed
 (g, f -> Just x) = e1
 (f, g -> Just y) = e2
 }}}
 But that seems wildly over the top.

 Laking an obvious design choice, I'm disinclined to make a change.

 Simon

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


More information about the Glasgow-haskell-bugs mailing list