Avoiding the hazards of orphan instances without dependency problems

David Feuer david.feuer at gmail.com
Mon Oct 20 02:08:27 UTC 2014


OK, so first off, I don't have anything against your pragma; I just think
that something akin to mine would be good to have too. Mine was not
intended to require both class and type to be in scope; if one of them is
not, then it should be given its full name:

{-# InstanceIn Module Foo.Class Type #-}
{-# InstanceIn Module Class Bar.Type #-}

As Edward Kmett explained to me, there are reasons for module authors not
to want to include instances for lens stuff—in particular, they apparently
tend to use a lot of non-portable code, but even aside from that, they may
just not want to have to deal with maintaining that particular code. This
leads to a slew of instances being dumped into lens modules, forcing the
lens package to depend on a bunch of others. What I'm suggesting is that
sticking {-# InstanceIn Data.Text.Lens Strict Data.Text.Lazy.Text
Data.Text.Text #-} into Control.Lens.Iso (and so on) would allow
Data.Text.Lens to be broken off into a separate package, removing the text
dependency from lens.

Note also: I described a way to (try to) support overlapping instances for
mine, but I think it would be valuable to offer mine even without that
feature (dropping the context stuff), if it's just too complex.

On Sun, Oct 19, 2014 at 9:43 PM, John Lato <jwlato at gmail.com> wrote:

> I fail to see how this doesn't help lens, unless we're assuming no buy-in
> from class declarations.  Also, your approach would require c*n pragmas to
> be declared, whereas mine only requires c.  Also your method seems to
> require having both the class and type in scope, in which case one could
> simply declare the instance in that module anyway.
>
> On Mon, Oct 20, 2014 at 9:29 AM, David Feuer <david.feuer at gmail.com>
> wrote:
>
>> I don't think your approach is flexible enough to accomplish the purpose.
>> For example, it does almost nothing to help lens. Even my approach should,
>> arguably, be extended transitively, allowing the named module to delegate
>> that authority, but such an extension could easily be put off till later.
>> On Oct 19, 2014 7:17 PM, "John Lato" <jwlato at gmail.com> wrote:
>>
>>> Thinking about this, I came to a slightly different scheme.  What if we
>>> instead add a pragma:
>>>
>>> {-# OrphanModule ClassName ModuleName #-}
>>>
>>> and furthermore require that, if OrphanModule is specified, all
>>> instances can *only* appear in the module where the class is defined, the
>>> involved types are defined, or the given OrphanModule?  We would also need
>>> to add support for the compiler to understand that multiple modules may
>>> appear under the same name, which might be a bit tricky to implement, but I
>>> think it's feasible (perhaps in a restricted manner).
>>>
>>> I think I'd prefer this when implementing orphan instances, and probably
>>> when writing the pragmas as well.
>>>
>>> On Mon, Oct 20, 2014 at 1:02 AM, David Feuer <david.feuer at gmail.com>
>>> wrote:
>>>
>>>> Orphan instances are bad. The standard approach to avoiding the orphan
>>>> hazard is to always put an instance declaration in the module that declares
>>>> the type or the one that declares the class. Unfortunately, this forces
>>>> packages like lens to have an ungodly number of dependencies. Yesterday, I
>>>> had a simple germ of an idea for solving this (fairly narrow) problem, at
>>>> least in some cases: allow a programmer to declare where an instance
>>>> declaration must be. I have no sense of sane syntax, but the rough idea is:
>>>>
>>>> {-# InstanceIn NamedModule [Context =>] C1 T1 [T2 ...] #-}
>>>>
>>>> This pragma would appear in a module declaring a class or type. The
>>>> named module would not have to be available, either now or ever, but
>>>> attempting to declare such an instance in any module *other* than the named
>>>> one would be an error by default, with a flag
>>>> -XAllowForbiddenInstancesAndInviteNasalDemons to turn it off. The optional
>>>> context allows multiple such pragmas to appear in the type/class-declaring
>>>> modules, to allow overlapping instances (all of them declared in advance).
>>>>
>>>> _______________________________________________
>>>> ghc-devs mailing list
>>>> ghc-devs at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/ghc-devs
>>>>
>>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/ghc-devs/attachments/20141019/37a8fb46/attachment.html>


More information about the ghc-devs mailing list