
Hi Ben On 4 Jan 2011, at 19:19, Ben Millwood wrote:
On Tue, Jan 4, 2011 at 1:21 PM, Conor McBride
wrote: Jón's proposal was to improve the latter situation by allowing the subclass to specify a default (partial) implementation of a superclass. So we might write
This, on its own, is not quite enough. For one thing, we need a way to switch it off. I should certainly be permitted to write something like
instance Applicative Blah where return = ... (<*>) = ... hiding instance Functor Blah
The use of 'hiding' here I'd object to, as it really isn't a good description of what's going on.
It's perhaps suboptimal. I chose "hiding" only because it's already a vaguely keywordy thing. It's only syntax. What's important is...
Personally I'd think it more clear to explicitly opt into an automatic instance: instance Applicative Blah where return = ... (<*>) = ... deriving (Functor) -- or something like that
[..]
but I think there is an argument to be made about how much of this process we want to be explicit and how much we want to be implicit.
...the argument about what should be implicit or explicit, opt-in or opt-out. In this argument, I disagree with you. I'd much rather it was notationally cheaper to go with the supplied default, provided deviation from the default is also fairly cheap (but explicit). My plan also has the advantage of cheaper backward compatibility (for this and other (future) class splittings). Note that in my example, return had moved to Applicative, pure had been dumped, and a typical Monad instance would look like instance Monad Maybe where Just x >>= f = f x Nothing >>= _ = Nothing return = Just -- where this implicitly opts into and extends the -- Applicative instance -- and also implicitly generates Functor We could not simply have said "deriving Applicative" here, because the default instance is incomplete. In general, one might want to override some but not all of the default instance, just as one does when default method implementations come from the class. There's a general engineering concern as well. The refactoring cost of splitting Applicative off as a lesser version of Monad, taking return, adding (<*>) derivable from (>>=) is much reduced by this choice. I'm sure it's not the only instance of a class we might discover is better split: the opt-in default reduces inertia to such design improvements. I'd certainly be happy with a different opt-out notation, but I would be unhappy if opting in (and overriding/extending) were made more complex than necessary to allow an opt-out default. All the best Conor