Functor hierarchy proposal and class system extension proposal
conor at strictlypositive.org
Tue Jan 4 20:59:15 CET 2011
On 4 Jan 2011, at 19:19, Ben Millwood wrote:
> On Tue, Jan 4, 2011 at 1:21 PM, Conor McBride
> <conor at strictlypositive.org> wrote:
>> Jón's proposal was to improve the latter situation by allowing the
>> to specify a default (partial) implementation of a superclass. So
>> we might
>> This, on its own, is not quite enough. For one thing, we need a way
>> switch it off. I should certainly be permitted to write something
>> 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
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
More information about the Haskell-prime