instance visibility

Simon Marlow marlowsd at
Wed Sep 24 14:22:32 EDT 2008

Claus Reinke wrote:

>>>> .., the only sensible way to think about instances is as global 
>>>> properties.
>> has nothing to do with bugs or misfeatures in GHC, it's a fact of 
>> Haskell 98.
> I thought my example demonstrated quite clearly that instances are *not* 
> global in Haskell.

Yes, I know that you can limit the visibilty of instances by using 
orphans in Haskell 98.  My point was that it is a mistake to design 
libraries this way, because it leads to a loss of abstraction.

>> This is even worse at the level of packages.  We can hide modules that 
>> are used internally to a package's implementation, but we can't hide 
>> the fact that a package used some non-standard instances internally, 
>> and furthermore we can't change this aspect of its implementation 
>> without changing the API.
> How do packages make a difference here? As long as I don't import
> base:Control.Monad.Error, the base:Control.Monad.Instances instances
> of Functor, say, are not visible in base:Control.Monad.

If I write a package that uses Control.Monad.Instances internally, that 
becomes visible via its API, and I cannot abstract away from this aspect 
of the implementation of my package.  This is an absolute failure of 
abstraction, and if we value abstraction (which we surely do?) then we 
should look for ways to fix the problem.

So one way is to look at changing the language, perhaps by supporting 
explicit re-export of instances.  Certainly that's a worthwhile 
direction to explore, but since our current language doesn't have this 
extension, we have to look for other ways to avoid the problem in the 
meantime.  The only solution is to not have orphan instances in the 
original library API, which is what I'm arguing for.

I think you misunderstood my point before (but you recognised that I 
repeated it :-).  I'm not trying to say that Haskell 98 only supports 
global instances, rather I'm saying we should think of it that way and 
design our libraries with global instances in mind, because otherwise we 
have serious problems with abstraction.

We agree that this is a failure of the language.  You seem to be arguing 
that we should pretend that the language is not broken in the hope that 
it gets fixed in the future - I think that's the wrong approach.

> Sadly, that has all been discussed to death already, and again, it is a 
> matter of being precise. "Orphan" instances are not wrong per se - they 
> encode and name the extent of type relations via modules, but one needs 
> to think carefully about their intended use and whether that use is 
> really supported by the language or just an illusion. Of the top of my 
> head, I can think of two uses:
> (a) having two instances of the same class for the same types in the    
> same program only works by "virtue" of #2356, so should be
>    avoided unless and until the positive aspects of #2356 are moved
>    from accident to design decision

Right, agreed.

> (b) giving clients control over which instances they want to use (eg,
>    use set A or set B, or neither) should work, and mostly does,
>    but may run into ghc #2182 and haddock #54. Also, it is    advisable 
> only for client applications, not for client libraries, as    long as 
> their users might run into unresolved aspect of (a).

I'm not sure what "client libraries" are, but I think I agree, if what 
you're saying is that orphan instances should be kept out of library 
APIs.  I'd also argue that they shouldn't be used in application code 
either, but the reasons are less compelling there.

> My preference would be to see ghc #2182, #2356 (for Haskell 98
> mode) and haddock #54 fixed. #2356 (for Ghc mode) is documented
> behaviour, I believe, inherited from Ghc's handling of overlapping
> instances, but there is no LANGUAGE extension specifying this
> behaviour, so it isn't portable.

I'll just point out that if we stop using orphan instances in library 
APIs, then #2182 is much less of an issue.

> Next, I'd like to see whether more
> control over instance re-export is permissible in theory and -if yes-
> would like to see it implemented and standardised.

Sure, please do!


More information about the Libraries mailing list