[Haskell-cafe] generalize RecordPuns and RecordWildCards to work with qualified names?

Simon Peyton-Jones simonpj at microsoft.com
Sun Aug 9 15:42:37 EDT 2009


Oh, now I get it, thanks.  This message concerns design choices for record-syntax-related GHC extensions.  Lennart, pls tune in.  You don’t need to have read the thread to understand this message.

| I think that Even refers to an example like this:
| 
| module A where
|   data A = A { a :: Int }
| 
| The following works:
| 
| {-# LANGUAGE NamedFieldPuns #-}
| module B where
|   import A
|   f (A { a }) = a
| 
| However, if we import "A" qualified, then punning does not seem to work:
| 
| {-# LANGUAGE NamedFieldPuns #-}
| module B where
|   import qualified A
|   f (A.A { a }) = a
| 
| This results in: Not in scope: `a'

Right.  What is happening is that GHC looks up the first 'a' (the one on the LHS) and finds it not in scope.  If you add -XDisambiguateRecordFields, it works fine.  But admittedly, the error message is unhelpful.  I could improve that.

Now on to the suggested change:

| {-# LANGUAGE NamedFieldPuns #-}
| module B where
|   import qualified A
| 
|   f (A.A { A.a }) = a
| 
| This results in: Qualified variable in pattern: A.a
| 
| Even is suggesting that instead of reporting an error, in the second
| case we could use the translation:
| 
|   f (A.A { A.a }) = a   -->   f (A.A { A.a = a })
| 
| (i.e., when punning occurs with a qualified name, use just the
| unqualified part of the name in the pattern)

Yes, that'd be possible.   But it seems debatable -- it doesn't *look* as if the pattern (A.A { A.a }) binds 'a' -- and it seems even less desirable in record construction and update.  To be concrete, would you expect these to work too?
  
  g a = A.A { A.a }     -->    g a = A.A { A.a = a }
  h x a = x { A.a }     -->    h x a = a { A.a = a }

In these cases, I think the abbreviated code looks too confusing.

With -XDisambiguateRecordFields you could say
  
  g a = A.A { a }

which seems better.  (But there's no help for record update, since we don’t know which data constructor is involved.)


So my current conclusion is: improve the error message, perhaps suggesting the flag -XDismabiguateRecordFields, but don't add the change you suggest.

Comments?

Simon



More information about the Haskell-Cafe mailing list