
On Sun, Sep 5, 2010 at 7:18 PM, David Menendez
On Sun, Sep 5, 2010 at 8:40 AM, John Lato
wrote: On Sat, Sep 4, 2010 at 12:34 PM, David Menendez
wrote:
On Fri, Sep 3, 2010 at 8:23 AM, John Lato
wrote: +1 for using the proper constraints, and especially for bringing over Pointed (and anything else that applies).
What's the argument for Pointed? Are there many types which are instances of Pointed but not Applicative? Are there many algorithms which require Pointed but not Applicative?
Having Pointed is categorically the right thing to do, which is why I argue for its inclusion.
Why is it categorically the right thing to do?
Because it's the proper abstraction underlying Applicative and Monad, as far as I understand category theory.
When Conor McBride was promoting the use of Applicative (then called Idiom), he provided several instances and algorithms showing that it was a useful generalization of Monad, and it still took several years and a few papers[1] before Applicative found its way into the standard library.
In other words, we didn't add Applicative and then discover Traversable later. Traversable was a big part of the argument for why Applicative is useful.
I take this in favor of my point. Applicative wasn't considered useful, so it wasn't included. Then Conor McBride shows that it is useful, but at that point it was too late and now we're stuck with pure, return, ap, liftA2, liftM2, etc. [1] Idioms: applicative programming with effects
http://www.cs.nott.ac.uk/~ctm/Idiom.pdf
Also, I think it would be prudent to avoid a situation with the possibility of turning into a rehash of the Functor/Applicative/Monad mess.
Granted, but let's not rush blindly in the opposite direction.
Are there any good reasons for not including it? Just because we don't have a use now doesn't mean it might not be useful in the future.
This is an argument for putting every member of the container API into its own independent class. Why make things more complicated for little or no benefit?
Not every member, but I would argue that type classes for containers should be much more fine-grained than anything I have seen proposed so far. I'm thinking of the collections provided by the .Net framework, i.e. a base ICollection interface, then IEnumerable, IList, and ISet on top of them. If an algorithm needs a list interface (integer-indexed, etc.), it can specify IList in the context, whereas if it only needs e.g. to check the length, or that a container is non-null, it can just specify ICollection and work with more data structures. I would be in favor of breaking it down further, and then the ListClass, SetClass, etc. would likely be classes with no methods, just a particular combination of superclasses. Edison is a good model too, although again I would go further. One category of containers that is currently impossible to express (with container-classes or Edison) is non-null data, e.g. SafeList. Adding support for these would be nice, and it would be easier with finer-grained dependencies. As an example, a List interface could work for both regular lists and SafeList's, but only if it didn't require Monoid (or similar) as a superclass constraint. That's hard to do with the current structure, but if you're just combining several type classes it's easy. At a minimum, I think that having extra classes for the specifics of e.g. Map or Queue interfaces is required for maximum utility. John