GHC support for the new "record" package

Edward Kmett ekmett at gmail.com
Fri Jan 23 22:23:54 UTC 2015


On Fri, Jan 23, 2015 at 5:06 PM, Adam Gundry <adam at well-typed.com> wrote:

> Thanks for the feedback, Iavor!
>
> On 23/01/15 19:30, Iavor Diatchki wrote:
> > 2. I would propose that we simplify things further, and provide just one
> > class for overloading:
> >
> > class Field (name :: Symbol)
> >             rec   rec'
> >             field field'
> >   | name rec         -> field
> >   , name rec'        -> field'
> >   , name rec  field' -> rec'
> >   , name rec' field  -> rec
> >   where
> >   field :: Functor f => Proxy name -> (field -> f field') ->
> >                                       (rec   -> f rec')
> >
> > I don't think we need to go into "lenses" at all, the `field` method
> > simply provides a functorial
> > update function similar to `mapM`.   Of course, one could use the `lens`
> > library to
> > get more functionality but this is entirely up to the programmer.
> >
> > When the ORF extension is enabled, GHC should simply generate an
> > instance of the class,
> > in a similar way to what the lens library does
>

> 3. I like the idea of `#x` desugaring into `field (Proxy :: Proxy "x")`,
> > but I don't like the concrete symbol choice:
> >   - # is a valid operator and a bunch of libraries use it, so it won't
> > be compatible with existing code.
>
> Ah. I didn't realise that, but assumed it was safe behind -XMagicHash.
> Yes, that's no good.
>
> >   - @x might be a better choice; then you could write things like:
> >     view @x      rec
> >   set  @x 3    rec
> >   over @x (+2) rec
>
> This could work, though it has the downside that we've been informally
> using @ for explicit type application for a long time! Does anyone know
> what the status of the proposed ExplicitTypeApplication extension is?


I'll confess I've been keen on stealing @foo for the purpose of (Proxy ::
Proxy foo) or (Proxy :: Proxy "foo") from the type application stuff for a
long time -- primarily because I remain rather dubious about how well the
type application stuff can work, once you take a type and it goes through a
usage/generalization cycle, the order of the types you can "apply" gets all
jumbled up, making type application very difficult to actually use. Proxies
on the other hand remain stable. I realize that I'm probably on the losing
side of that debate, however. But I think it is fair to say that that
little bit of dangling syntax will be a bone that is heavily fought over. ;)

>   - another nice idea (due to Eric Mertens, aka glguy), which allows us
> > to avoid additional special syntax is as follows:
> >     - instead of using special syntax, reuse the module system
> >     - designate a "magic" module name (e.g., GHC.Records)
> >     - when the renamer sees a name imported from that module, it
> > "resolves" the name by desugaring it into whatever we want
> >     - For example, if `GHC.Records.x` desugars into `field (Proxy ::
> > Proxy "x")`, we could write things like this:
> >
> > import GHC.Records as R
> >
> > view R.x      rec
> > set  R.x 3    rec
> > over R.x (+2) rec
>
> Interesting; I think Edward suggested something similar earlier in this
> thread. Avoiding a special syntax is a definite advantage, but the need
> for a qualified name makes composing the resulting lenses a bit tiresome
> (R.x.R.y.R.z or R.x . R.y . R.z). I suppose one could do
>
>     import GHC.Records (x, y, z)
>     import MyModule hiding (x, y, z)
>
> but having to manually hide the selector functions and bring into scope
> the lenses is also annoying.


In the suggestion I made as a (c) option for how to proceed around field
names a few posts back in this thread I was hinting towards having an
explicit use of {| foo :: x |} somewhere in the module provide an implicit
import of

import Field (foo)

then users can always reference Field.foo explicitly if they don't have
such in local scope, and names all share a common source.

Of course this was in the context a Nikita style {| ... |} rather than the
ORF { .. }.

If the Nikita records didn't make an accessor, because there's no way for
them to really do so, then there'd be nothing to conflict with.

Being able to use import and use them with ORF-style records would just be
gravy then. Users would be able to get those out of the box.

-Edward
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20150123/89df1084/attachment-0001.html>


More information about the ghc-devs mailing list