#3632: lift restrictions on records with existential fields, especially in the
presence of class constraints
----------------------------------------------------+-----------------------
    Reporter:  eflister                             |        Owner:             
     
        Type:  feature request                      |       Status:  new        
     
    Priority:  normal                               |    Milestone:             
     
   Component:  Compiler                             |      Version:  6.10.4     
     
    Severity:  normal                               |   Resolution:             
     
    Keywords:  existential records accessor update  |   Difficulty:  Unknown    
     
    Testcase:                                       |           Os:  
Unknown/Multiple
Architecture:  Unknown/Multiple                     |  
----------------------------------------------------+-----------------------
Changes (by simonpj):

  * difficulty:  => Unknown

Old description:

> the attached file demos the use of a record with an existential field
> with a class constraint.  it shows several cases where lifting the
> current restrictions on accessing and updating this field would be both
> well-defined and useful.
>
> here is the record definition; the dur field is existential, but
> constrained to be in class NoteDur.
>
> {{{
> data Note = forall x . NoteDur x => Note {
>       midiNum :: Int -- 0-255
>     , vel     :: Int -- 0-255
>     , chan    :: Int -- 0-15
>     , measure :: Integral a => a
>     , beat    :: Int
>     , subdiv  :: RealFrac a => a -- % of beat
>     , dur     :: x
>     }
> }}}
>
> here is a walk through of places in the code where the current
> restrictions are unnecessary and intrusive:
>
> lines 64-95 -- these functions wouldn't be necessary if record update
> syntax were enabled for both existential and non-existential fields.  i
> know 6.12 introduces it for non-existentials, but i don't see why it
> isn't also possible for existential fields (even without a class
> constraint).  lines 33-35 and 60 show how much nicer it is to use regular
> updater syntax in this case.
>
> the same is true for existential accessors when there is a class
> constraint -- there's no need to restrict this situation because the
> accessor can have type:
> fieldName :: (SomeClass x) => Record -> x
> line 142 shows a case where this would be very nice to have.
>
> line 100 + 107 -- the foralls could be implicit (maybe offer an extention
> that would allow them to be implicit)
>
> lines 134-136 compared to 138-139 show how additional factoring could be
> achieved if one were allowed to pattern match on the type of an
> existential with class constraints.
>
> lines 124-127 show how it would be nice to have existential classes
>
> lastly, allow curried updater functions:
> (rec {field = }) 5
> instead of
> (\x -> (rec {field = x})) 5

New description:

 the attached file demos the use of a record with an existential field with
 a class constraint.  it shows several cases where lifting the current
 restrictions on accessing and updating this field would be both well-
 defined and useful.

 here is the record definition; the dur field is existential, but
 constrained to be in class NoteDur.

 {{{
 data Note = forall x . NoteDur x => Note {
       midiNum :: Int -- 0-255
     , vel     :: Int -- 0-255
     , chan    :: Int -- 0-15
     , measure :: Integral a => a
     , beat    :: Int
     , subdiv  :: RealFrac a => a -- % of beat
     , dur     :: x
     }
 }}}

 here is a walk through of places in the code where the current
 restrictions are unnecessary and intrusive:

  1. lines 64-95 -- these functions wouldn't be necessary if record update
 syntax were enabled for both existential and non-existential fields.  i
 know 6.12 introduces it for non-existentials, but i don't see why it isn't
 also possible for existential fields (even without a class constraint).
 lines 33-35 and 60 show how much nicer it is to use regular updater syntax
 in this case.

  2. Line 142.  The same is true for existential accessors when there is a
 class constraint -- there's no need to restrict this situation because the
 accessor can have type:
 {{{
 fieldName :: (SomeClass x) => Record -> x
 }}}
    line 142 shows a case where this would be very nice to have.

  3. line 100 + 107 -- the foralls could be implicit (maybe offer an
 extention that would allow them to be implicit)

  4. lines 134-136 compared to 138-139 show how additional factoring could
 be achieved if one were allowed to pattern match on the type of an
 existential with class constraints.

  5. lines 124-127 show how it would be nice to have existential classes

  6. lastly, allow curried updater functions: `(rec {field = }) 5` instead
 of `(\x -> (rec {field = x})) 5`

Comment:

 Brief responses.

  1. It's not all that simple; if a record had two existential fields (e.g.
 `dur1,dur2::x`), you'd have to update them both simultaneously.  But the
 rule could, and probably should, be: if the desugared version typechecks,
 so should the record-update form.  So, yes.

  2. Either I misunderstand you, or this is unsound.  Remember, the type
 'x' is unknown, so it can't be supplied by the caller. So, as far as I can
 see this is a non-starter.

  3. This is already possible
 {{{
 data ModDur where
   Dotted :: NoteDur x => x -> ModDur
   Triplet :: DurBase -> ModDur
 }}}

  4. I don't understand this at all.  In your example
 {{{
     quarters (x y) = quarters y * case x of
 }}}
     what are you expecting 'x' to be bound to?  The constructor itself?
 If so, you are way beyond Haskell. Check out [http://www-
 staff.it.uts.edu.au/~cbj/patterns/ Barry Jay's excellent work].

  5. I have no idea what you mean here.

  6. Quite possible, along the lines of tuple sections.  The
 complexity/benefit ratio is debatable; my nose says "not quite worth it"
 but I'd be interested to know what others think.

 So for me (1) is the thing that would be worth fixing.  I remember
 spending a while thinking about doing this a year ago, but I didn't do it
 for some reason.  I think it might have been to do with generating
 sensible error messages.

 Simon

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/3632#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to