GHC support for the new "record" package

Edward Kmett ekmett at gmail.com
Tue Jan 27 00:59:20 UTC 2015


I'm also rather worried, looking over the IV proposal, that it just doesn't
actually work.

We actually tried the code under "Haskell 98 records" back when Gundry
first started his proposal and it fell apart when you went to compose them.

A fundep/class associated type in the class is a stronger constraint that a
type equality defined on an individual instance.

I don't see how

@foo . @bar . @baz

(or #foo . #bar . #baz as would be written under the concrete proposal on
the wiki)

is ever supposed to figure out the intermediate types when working
polymorphically in the data type involved.

What happens when the type of that chain of accessors is left to inference?
You get stuck wallowing in AllowAmbiguousTypes territory:

(#foo . #bar . #baz) :: (IV "foo" (c -> d), IV "bar" (b -> c), IV "baz" (a
-> b)) => a -> d

has a variables 'b' and 'c' that don't occur on the right hand side, and
which are only determinable by knowing that the instances you expect to see
look something like:

instance (a ~ Bool) => IV "x" (S -> a) where
  iv (MkS x) = x

but that is too weak to figure out that "S" determines "a" unless S is
already known, even if we just limit ourselves to field accessors as
functions.

-Edward


On Mon, Jan 26, 2015 at 7:43 PM, Edward Kmett <ekmett at gmail.com> wrote:

> On Mon, Jan 26, 2015 at 4:41 PM, Simon Peyton Jones <simonpj at microsoft.com
> > wrote:
>
>>    Personally, I don't like the sigil mangled version at all.
>>
>> You don’t comment on the relationship with implicit parameters.  Are they
>> ok with sigils?
>>
>
> I don't have too many opinions about implicit parameters, but they don't
> really see a lot of use, which makes me somewhat leery of copying the
> pattern. ;)
>
>   If it is then further encumbered by a combinator it is now several
>> symbols longer at every single use site than other alternatives put forth
>> in this thread. =(
>>
>> No, as Nikita says, under the “Redesign” proposal it would be #bar . #baz
>>
> The problem is that if you make #bar an instance of Category so that it
> can use (.) then it will fail to allow type changing re-assignment.
>
>
>>  The import Field trick is magic, yes, but it has the benefit of being
>> the first approach I've seen where the resulting syntax can be as light as
>> what the user can generate by hand today.
>>
>> That’s why I added it to the “Redesign” page. It seems viable to me; a
>> clever idea, thank you.  Still, personally I prefer #x because of the link
>> with implicit parameters.  It would be interesting to know what others
>> think.
>>
> Admittedly @bar . @baz has the benefit that it introduces no namespacing
> conflicts at all.
>
> If we really had to go with some kind of sigil based solution, I _could_
> rally behind that one, but I do like it a lot less than the import trick,
> if only because the import trick gets rid of that last '@' and space we
> have on every accessor and you have to admit that the existing
>
> foo^.bar.baz.quux
>
> idiom reads a lot more cleanly than
>
> foo ^. @bar . @baz . @quux
>
> ever can.
>
> (I used @foo above because it avoids any potential conflict with existing
> user code as @ isn't a legal operator)
>
>  I'm confess, I, like many in this thread, am less than comfortable with
>> the notion of bringing chunks of lens into base. Frankly, I'd casually
>> dismissed such concerns as a job for Haskell 2025. ;) However, I've been
>> trying to consider it with an open mind here, because the alternatives
>> proposed thus far lock in uglier code than the status quo with more
>> limitations while simultaneously being harder to explain.
>>
>> I don’t think anyone is suggesting adding any of lens are they?  Which
>> bits did you think were being suggested for addition?
>>
> I was mostly referring to the use of the (a -> f b) -> s -> f t form.
>
>>  Note: once you start using a data-type then (.) necessarily fails to
>> allow you to ever do type changing assignment, due to the shape of
>> Category, or you have to use yet another operator, so that snippet cannot
>> work without giving up something we can do today. OTOH: Using the
>> lens-style story, no types are needed here that isn't already available in
>> base and, done right, no existing operators need be stolen from the user,
>> and type changing assignment is trivial.
>>
>> I’m afraid I couldn’t understand this paragraph at all.  Perhaps some
>> examples would help, to illustrate
>>
> what you mean?
>>
> I was writing that paragraph in response to your query if it'd make sense
> to have the @foo return some data type: It comes at a rather high cost.
>
> Lens gets away with using (.) to compose because its really using
> functions, with a funny mapM-like shape (a -> f b) -> (s -> f t) is still a
> function on the outside, it just happens to have a (co)domain that also
> looks like a function (a -> f b).
>
> If we make the outside type constructor a data type with its own Category
> instance, and just go `Accessor s a` then it either loses its ability to
> change out types in s  -- e.g. change out the type of the second member in
> a pair, or it loses its ability to compose.
>
> We gave up the latter to make Gundry's proposal work as we were forced
> into that shape by trying to return a combinators that could be overloaded
> to act as an existing accessor function.
>
> To keep categorical composition for the accessor, you might at first think
> we can use a product kind or something to get Accessor '(s,t) '(a,b) with
> both indices but that gets stuck when you go to define `id`, so necessarily
> such a version of things winds up needing its own set of combinators.
>
> -Edward
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20150126/76ff5bb4/attachment-0001.html>


More information about the ghc-devs mailing list