Superclass defaults

Bas van Dijk v.dijk.bas at gmail.com
Sun Aug 28 23:21:04 CEST 2011


On 22 August 2011 10:10, Simon Peyton-Jones <simonpj at microsoft.com> wrote:
> | > I don't completely understant how does it work. Does client need to enable
> | > language extension to get default instances?
> |
> | I think that the extension would only be required to *define them*,
> | not for them to be generated. The more conservative choice would
> | indeed be to require the extension for both, though.
>
> Yes. I've clarified http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances to say this.
>
> | > Also proposal cannot fix Functor/Applicative/Monad problem without breaking
> | > client code. It requires explicit opt-out but client may define Applicative
> | > instance. And unless "hiding" is added it will result in compile error.
> |
> | I think the intention (at least as I understand it) is that a
> | superclass default is only used to generate an instance if there is
> | not already some suitable instance in scope, just like a default
> | method is only used if there is not some explicit definition for the
> | method in the instance.
>
> Actually that is not what Conor and I proposed.  See http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances.  Under "Variations" we discuss the "silent-opt-out" choice.  But it's bad enough knowing exactly what instances are in scope (given that they are not named), let alone having that control what further instances are or are not generated!  For superclass defaults there is no such ambiguity.
>
> Simon
>
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
>

Won't option 1 "Reject this as a duplicate instance declaration, which
indeed it is." conflict with design goal 1: "a class C can be
re-factored into a class C with a superclass S, without disturbing any
clients"?

Take the transformers package for example. It defines lot's of
instances of Functor and Applicative for its monad transformers.
Doesn't transformers have to be changed if we go for option 1 (by
either dropping the Functor and Applicative instances or listing
hiding clauses in the Monad instances) thereby seriously conflicting
with the design goal of not disturbing any clients.

I expected the semantics to be like option 3: "Allow the explicit to
supersede the intrinsic default silently". It has the advantage of:

1) Not disturbing any client code.

2) Giving the ability to define optimized implementations if you're
not happy with the default ones (without using the hiding mechanism).

3) Feeling very much like the semantics of default methods thereby
conforming to the rule of least surprise.

The argument against option 3, which I quote:

"Option 3 avoids that problem but risks perplexity: if I make use of
some cool package which introduces some Foo :: * -> *, I might notice
that Foo is a monad and add a Monad Foo instance in my own code,
expecting the Applicative Foo instance to be generated in concert; to
my horror, I find my code has subtle bugs because the package
introduced a different, non-monadic, Applicative Foo instance which
I'm accidentally using instead."

talks about "subtle bugs". Could you give an example of such a bug?

I would expect that the non-monadic Applicative Foo instance is always
 somehow "compatible" with the monadic one. However I don't have a
clear definition of "compatible" yet...

Thanks,

Bas



More information about the Glasgow-haskell-users mailing list