Fwd: Re: Pointed and Traversable

Petr Pudlák petr.mvd at gmail.com
Fri Aug 30 17:06:36 CEST 2013

I forgot to add "libraries" as a recipient, so I'm forwarding the mail.

-------- Pu*vodní zpráva --------
Pr(edme(t: 	Re: Pointed and Traversable
Datum: 	Fri, 30 Aug 2013 16:59:45 +0200
Od: 	Petr Pudlák <petr.mvd at gmail.com>
Komu: 	Edward Kmett <ekmett at gmail.com>
Kopie: 	Henning Thielemann <schlepptop at henning-thielemann.de>, Frantisek 
Farka <ffarka at gmail.com>

Dne 08/26/2013 10:26 PM, Edward Kmett napsal(a):
> I can't speak well to SHE's implementation but there are a few 
> tensions in the design space of how to handle default superclass 
> instances in a language like Haskell that makes them not perfectly 
> solve the issue that Haskell generally sucks at dealing with deep 
> accurate typeclass hierarchies.
> 1.) When you have a complex lattice of types rather than a linear 
> chain, you're going to get a lot of ways to derive the common default 
> functionality.
>  class Functor f => Applicative f
>     gives one way to automatically define fmap
>  class Functor f => Traversable f
>    gives another way to define fmap for free
>  class Functor f => Comonad f
>    gives a third way to define fmap for free
> In general when you have a lattice of properties points above you in 
> the lattice will start getting an exploding number of definitions from 
> classes below them, leading to limited utility for any 'hiding' based 
> mechanism as you've traded n definitions for n hiding declarations.
True, that's an important issue to solve, I'll have to think about it. 
One idea that emerges is to borrow some concepts from OOP/Java and to 
distinguish "interface"-like type classes that have no defaults (just 
the ones we have now) and "class"-like type classes that can have 
defaults. And "class"-like could "descend" only from at most one other 
"class"-like type class. (This is perhaps somewhat similar to 
http://repetae.net/recent/out/classalias.html, which distinguishes 
classes from class aliases.)

> 2.) As typeclass hierarchies become deeper with more refined notions, 
> say, Functor, Semiapplicative, Semimonad, Pointed, Applicative, Monad 
> (note the last 2 only have laws with no methods in the perfect world), 
> you wind up being able to get fewer default/mutual definitions to work 
> at any individual level of the hierarchy.
> 3) Product-like constructions, monad transformers, etc. still need 
> definitions for every point in the typeclass lattice. Since almost all 
> of my code is polymorphic in this style, it turns out I almost never 
> get to use the instances that would be supplied by a default 
> superclass system.

Could you please give an example? You mean that if let's say we 
introduce Applicative => Monad with the default superclass system, you'd 
still have to refactor your code?

> I generally favor the notion of adding default definitions for 
> superclass methods and adding 'default instances', I just think it is 
> necessary to point out that it doesn't help nearly as much as everyone 
> thinks it will, when it comes to the pains induced by retroactively 
> adding a finer grained inheritance hierarchy.
> Culturally, it is a hard sell to the average Haskeller to get them to 
> embrace a class that doesn't give them any new methods, so we wind up 
> with an awkward culture that favors a few powerful abstractions over 
> the full menagerie of accurate types.
I'd say it depends how it's presented. The main selling point for adding 
fine grained hierarchy is that more things get a common type class. Like 
we could say we don't need Functors or Applicatives because most of them 
are Monads anyway, but still people agree that Functors are useful and 
needed. So I think the main objection of the average Haskeller is that 
introducing a new type class breaks (his) stuff. If we can find a 
mechanism how to avoid that, I'd say (s)he wouldn't mind (perhaps even 

   Best regards,

> -Edward
> On Mon, Aug 26, 2013 at 2:18 PM, Petr Pudlák <petr.mvd at gmail.com 
> <mailto:petr.mvd at gmail.com>> wrote:
>     One of our students is currently exploring how to extend Haskell
>     so that splitting classes into more fine-grained hierarchy won't
>     cause these problems:
>     https://groups.google.com/forum/#!topic/haskell-cafe/W1NbrikzgCQ
>     <https://groups.google.com/forum/#%21topic/haskell-cafe/W1NbrikzgCQ>
>     along the lines of
>     http://ghc.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances
>     Unfortunately, it seems his message went unnoticed by Haskell
>     community.
>       Best regards,
>       Petr Pudlak
>     Dne 08/26/2013 07:16 PM, Edward Kmett napsal(a):
>>     There are several uses of Pointed as a separate beast from
>>     Applicative. In particular it comes up when we talk about "affine
>>     traversals", and would let us refine the type hierarchy of lens,
>>     so you'd think I'd be for it.
>>     However, to move it into its own class would require literally
>>     everyone who currently has an Applicative instance to clutter
>>     their code with CPPs.
>>     Even as the author of the Pointed class, I personally find that
>>     the benefit of the change doesn't warrant the impact of the change.
>>     -Edward
>>     On Mon, Aug 26, 2013 at 12:59 PM, Henning Thielemann
>>     <schlepptop at henning-thielemann.de
>>     <mailto:schlepptop at henning-thielemann.de>> wrote:
>>         There was a lot of discussion about separating "pure" from
>>         Applicative and putting it into a Pointed class. If I
>>         remember correctly, the main counter argument was that 'pure'
>>         alone does not satisfy interesting laws. There are only such
>>         laws in connection with the Applicative class.
>>         Now, in some situations I liked to have a generalized
>>         unfoldr. I can build this from "pure" and "sequenceA" using
>>         the State monad:
>>         unfoldr :: (Pointed t, Traversable t) => (s -> (a, s)) -> s
>>         -> t a
>>         unfoldr = evalState . sequenceA . pure . state
>>         One could state a law like:
>>            traverse f (pure a) == traverse id (pure (f a))
>>         Would this justify to move "pure" into a new Pointed class?
>>         _______________________________________________
>>         Libraries mailing list
>>         Libraries at haskell.org <mailto:Libraries at haskell.org>
>>         http://www.haskell.org/mailman/listinfo/libraries
>>     _______________________________________________
>>     Libraries mailing list
>>     Libraries at haskell.org  <mailto:Libraries at haskell.org>
>>     http://www.haskell.org/mailman/listinfo/libraries

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20130830/7ed892ed/attachment.htm>

More information about the Libraries mailing list