

# Default superclass instances









A matter of much consternation, here is a proposal to allow type class declarations to include default instance declarations for their superclasses. It's based on [ Jón Fairbairn's proposal](http://www.haskell.org//pipermail/haskellprime/2006August/001587.html), but it has a more explicit 'off switch' and the policy on cornercases is rejection. Credit is due also to the [ class system extension proposal](http://www.haskell.org/haskellwiki/Class_system_extension_proposal) and its ancestors, in particular, John Meacham's [ class alias](http://repetae.net/recent/out/classalias.html) proposal.









We may distinguish two uses of superclasses (not necessarily exclusive). A class can *widen* its superclass, extending its interface with new functionality (e.g., adding an inverse to a monoid to obtain a group  inversion seldom provides an implementation of composition). A class can *deepen* its superclass (e.g., an implementation of Traversable f delivers at least enough technology to deliver Foldable f and Functor f). This proposal concerns the latter phenomenon, which is currently such a nuisance that Functor and Applicative are not superclasses of Monad. Nobody wants to be forced to write Functor and Applicative instances, just to access the Monad interface. Moreover, any proposal to refine the library by splitting a type class into depthlayers is (rightly!) greeted with howls of protest as an absence of superclass instances gives rise to breakage of the existing codebase.



We may distinguish two uses of superclasses (not necessarily exclusive).






 A class can *widen* its superclass, extending its interface with new functionality (e.g., adding an inverse to a monoid to obtain a group  inversion seldom provides an implementation of composition).



 A class can *deepen* its superclass (e.g., an implementation of Traversable f delivers at least enough technology to deliver Foldable f and Functor f).






Concretely, the proposal is to






 allow class declarations to embed instance declarations for some, none, or all of their given superclass constraints, provided all such instances have distinct classes. We say that superclasses with default implementations are **intrinsic** superclasses. Yes to



(**SLPJ** I don't understand this distinction clearly.)






```wiki



class Functor f => Applicative f where



return :: x > f x



(<*>) :: f (s > t) > f s > f t



(>>) :: f s > f t > f t



fs >> ft = return (flip const) <*> fs <*> ft



instance Functor f where



fmap = (<*>) . return






class Applicative f => Monad f where



(>>=) :: f a > (a > f b) > f b



instance Applicative f where



ff <*> fs = ff >>= \ f > fs >>= \ s > return (f s)



```






This



proposal concerns the latter phenomenon, which is currently such a



nuisance that Functor and Applicative are not superclasses of



Monad. Nobody wants to be forced to write Functor and Applicative



instances, just to access the Monad interface. Moreover, any proposal



to refine the library by splitting a type class into depthlayers is



(rightly!) greeted with howls of protest as an absence of superclass



instances gives rise to breakage of the existing codebase.






but no to






```wiki



class (Tweedle dum, Tweedle dee) => Rum dum dee where



instance Tweedle dum where ...



instance Tweedle dee where ...



```



Default superclass instances are implemented in the



[ Strathclyde Haskell Enhancement](http://personal.cis.strath.ac.uk/~conor/pub/she/superclass.html).



They should enable some tidying of



the library, with relatively few tears. Moreover, they should allow us



to deepen type class hierarchies as we learn. Retaining backward



compatibility in relative silence is the motivation for an optin



default.






 let subclass instance declarations spawn intrinsic superclass instances by default  if we have



## The proposal






```wiki



class Bar t[x] => Foo x where



instance Bar t[x] where ...






instance C => Foo s where ...



```



Concretely, the proposal is as follows.






### Default superclass instances









we automatically acquire a default superclass instance



First, we allow a class declaration to include a **default superclass instance delcaration** for some, none, or all of its superclass constraints. We say that superclasses with default implementations are **intrinsic** superclasses. Example:






```wiki



instance C => Bar t[s] where ...



class Functor f => Applicative f where



return :: x > f x



(<*>) :: f (s > t) > f s > f t






(>>) :: f s > f t > f t



fs >> ft = return (flip const) <*> fs <*> ft






instance Functor f where



fmap = (<*>) . return



```






 let subclass instance declarations provide and override the methods of their intrinsic superclasses with no extra delimitation; so we may write






```wiki



instance Monad Blah where



return x = ...



ba >>= bf = ...



```



Note the `instance` declaration nested inside the `class` declaration. This is the default superclass instance declaration, and `Functor` thereby becomes an intrisic superclass of `Applicative`. Moreover, note that the definition of `fmap` uses the `<*>` operation of `Applicative`; that is the whole point!









and acquire the Monad instance, along with fully formed Applicative and Functor instances. By requiring that intrinsic superclasses be classdistinct, we ensure that the distribution of methods to spawned instances is unambiguous. Moreover, local overrides beat the default. If we write



Here is another example:






```wiki



instance Monad Blah where



return x = ...



ba >>= bf = ...



bs >> bt = ...



class Applicative f => Monad f where



(>>=) :: f a > (a > f b) > f b



instance Applicative f where



ff <*> fs = ff >>= \ f > fs >>= \ s > return (f s)



```









we override the default (\>\>) but keep the (\<\*\>) in the spawned Applicative instance.



Here, `Applicative` is an intrinsic superclass of `Monad`.






### Instance declarations









A default superclass instance in a class declaration for class C



has an effect on the instance declarations for C.









 to inhibit defaultspawning with the syntax



Specifically:






 An instance declaration






```wiki



instance Sub x where



...



hiding instance Super



instance Q => C ty where ...defs...



```






for class C generates an extra instance



declaration






which acts to prevent the generation of instances for Super and all of Super's intrinsic superclasses in turn. We need this, so that we can write



```wiki



instance Q => Si ty where ....



```






```wiki



instance Monad Blah where



return x = ...



ba >>= bf = ...



hiding instance Functor



for each intrinsic superclass Si of C






instance Traversable Blah where



traverse f bx = ...  inducing a default implementation of Functor



```



 The method definitions in `...defs...` are distributed to the



appropriate instance declaration, according to which class



the method belongs to.






 Any methods that are not specified explicitly are "filled in"



from the default definition given in the default superclass instance.



(If there is no default definition, then a warning is produced,



and a definition that calls `error` is used instead.)






or indeed to turn off all the defaults and provide a standalone Functor instance.






 while we're about it, to allow multiheaded instance declarations for classdisjoint conjunctions, with the same semantics for constraint duplication and method distribution as for the defaults, so



For example, assume the class declaration for `Monad` above. Then



this instance declaration:






```wiki



instance S => (C x, C' x) where



methodOfC = ...



methodOfC' = ...



```



```wiki



instance Monad m where



(>>=) = ...blah...



(<*) = ...bleh...



```









is short for



would generate an extra instance declaration for the instrinsic superclass `Applicative`,



with the methods distributed appropriately:






```wiki



instance S => C x where



methodOfC = ...



instance S => C' x where



methodOfC' = ...



instance Monad m where



(>>=) = ...blah...






instance Applicative m where



(<*) = ...bleh...  Programmer specified






ff <*> fs = ff >>= \ f > fs >>= \ s > return (f s)



 From the default superclass instance



```









This proposal fits handily with the [kind Fact proposal](kindfact), which allows multiple constraints to be abbreviated by ordinary type synonyms.



We call these extra instance declarations an **intrinsic instance declaration**.



(The term "derived instance" is already taken!)









Default superclass instances are implemented in the [ Strathclyde Haskell Enhancement](http://personal.cis.strath.ac.uk/~conor/pub/she/superclass.html). They should enable some tidying of the library, with relatively few tears. Moreover, they should allow us to deepen type class hierarchies as we learn. Retaining backward compatibility in relative silence is the motivation for an optin default.



This process is recursive. Since `Functor` is an intrinsic superclass of `Applicative`,



the intrinsic instance for `Applicative` recursively



generates an intrinsic instance for `Functor`:






```wiki



instance Functor m where



fmap = (<*>) . return  From default superclass instance



```






## The optout mechanism






Oleg and others note: just because you can make default instances, they are not always the instances you want. A key example is






Just because you can make default instances, they are not always the instances you want. A key example is






```wiki



instance Monad m => Monad (ReaderT r m) where ...



```









which would give us by default



which would give us by default the intrinsic instance






```wiki



instance Monad m => Applicative (ReaderT r m) where ...

...  ...  @@ 140,14 +165,135 @@ thus preventing us adding the more general 


```









The optout is crucial, but relatively cheap.



To inhibit the generation of an intrinsic instance declaration, one can use a



`hiding` clause in the instance declaration:






```wiki



instance Sub x where



...



hiding instance Super



```









which acts to prevent the generation of instances for Super and all of



Super's intrinsic superclasses in turn. For example:



write






```wiki



instance Monad m => Monad (ReaderT r m) where ...



return x = ...



ba >>= bf = ...



hiding instance Applicative



```









The `hiding` clause applies to all the intrinsic instances generated



from an instance declaration. For example, we might write






```wiki



instance Monad T where



return x = ...



ba >>= bf = ...



hiding instance Functor



```









Note that `Functor` is only an indirect intrinsic superclass of `Monad`, via `Applicative`.



So the above instance would generate an intrinsic instance for `Applicative` but not for `Functor`.









Jón's proposal had a more subtle optout policy, namely that an



intrinsic superclass can be quietly preempted by an instance for the



superclass from a prior or the present module. Note that to declare an



instance of the subclass, one must produce an instance of the



superclass by the same module at the latest.









This quiet exclusion



policy is not enough to handle the case of multiple candidate



intrinsic instances arising from multiple intrinsic superclasses (e.g.,



`Traversable` and `Monad` giving competing `Functor` instances), so some



explicit form is required. The question for us, then, is what should



happen if an intrinsic superclass not explicitly hidden were to clash



with an explicit instance from the same or a prior module. We could






1. Reject this as a duplicate instance declaration, which indeed it is.



1. Allow the explicit to supersede the intrinsic default, but issue a warning suggesting to either remove the explicit instance or add an explicit optout, or



1. Allow the explicit to supersede the intrinsic default silently.









As it stands, we propose option 1 as somehow the principled thing to



do. We acknowledge that it creates an issue with legacy code,



precisely because there are plenty of places where we have written the



full stack of instances, often just doing the obvious default thing:



these should be cleaned up, sooner or later.









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, nonmonadic, `Applicative Foo` instance which I'm



accidentally using instead. Option 2 is certainly worth considering as



a pragmatic transitional compromise, although the 'transitional' has a



dangerous tendency to be permanent.






## Multiheaded instance declarations









While we're about it, to allow multiheaded instance declarations for classdisjoint conjunctions, with the same semantics for constraint duplication and method distribution as for the defaults, so






```wiki



instance S => (C x, C' x) where



methodOfC = ...



methodOfC' = ...



```









is short for






```wiki



instance S => C x where



methodOfC = ...



instance S => C' x where



methodOfC' = ...



```









This proposal fits handily with the [kind Fact proposal](kindfact),



which allows multiple constraints to be abbreviated by



ordinary type synonyms. So we might write






Jón's proposal had a more subtle optout policy, namely that an intrinsic superclass can be quietly preempted by an instance for the superclass from a prior or the present module. Note that to declare an instance of the subclass, one must produce an instance of the superclass by the same module at the latest. This quiet exclusion policy is not enough to handle the case of multiple candidate instances arising from multiple intrinsic superclasses (e.g., Traversable and Monad giving competing Functor instances), so some explicit form is required. The question for us, then, is what should happen if an intrinsic superclass not explicitly hidden were to clash with an explicit instance from the same or a prior module. We could



```wiki



type Stringy x = (Read x, Show s)



instance Stringy Int where



read = ...



show = ...



```






1. reject this as a duplicate instance declaration, which indeed it is, or



1. allow the explicit to supersede the intrinsic default, but issue a warning suggesting to either remove the explicit instance or add an explicit optout, or



1. allow the explicit to supersede the intrinsic default silently.






The common factor is that one instance declaration is expanded into



several with the method definitions distributed appropriately among



them.






## Details









Each default superclass instance declaration in a `class` declaration must be for



a distinct class. So one of these is OK and the other is not:






```wiki



 This is ILLEGAL



class (Tweedle dum, Tweedle dee) => Rum dum dee where



instance Tweedle dum where ...



instance Tweedle dee where ...






 But this is OK



class (Tweedle dum, Tweedle dee) => Rum dum dee where



instance Tweedle dee where ...



```









As it stands, we propose option 1 as somehow the principled thing to do. We acknowledge that it creates an issue with legacy code, precisely because there are plenty of places where we have written the full stack of instances, often just doing the obvious default thing: these should be cleaned up, sooner or later. 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, nonmonadic, `Applicative Foo` instance which I'm accidentally using instead. Option 2 is certainly worth considering as a pragmatic transitional compromise, although the 'transitional' has a dangerous tendency to be permanent. 


By requiring that intrinsic superclasses be classdistinct, we ensure that the distribution of methods to spawned instances is unambiguous. 