From: Ivan Lazar Miljenovic <ivan.miljenovic@gmail.com>

When I released the first version of container-classes (which I hacked
on during AusHac), some people said I should split out the various
folding, etc. into duplicates of the current Foldable class, etc.
rather than having large monolithic classes.

I've been working on this (see my more recent email with the subject
along the lines of "fighting the type system"), and I think I've
worked out how to do this:

* Have one version of the class (when this makes sense) for values of kind *

* Have another version that's closer to the original class for kind *
-> *  but allowing restrictions (e.g. allowing Set to be an instance
of Functor).  This is based upon Ganesh Sittampalam's rmonad package
(http://hackage.haskell.org/package/rmonad).

Rather than my original goal of forcing all kind * -> * values to be
instances of the kind * classes, my new approach is to write instances
that automatically make all instances of a * ->  * class to also be an
instance of the kind * class, and to use a newtype wrapper with a
phantom type value to allow lifting/promotion of a kind * value to a
kind * -> * value (e.g. "foo :: (Word8 -> Word8) -> ByteString ->
ByteString; foo f = unpromote . fmap f . Promote" is a valid usage,
rather than using the kind * function of rigidMap).

My goal with this is that if I have duplicated a class Foo to allow
restricted values, then it should be a drop-in replacement for the
original in terms of _usage_ (i.e. the class and method/function names
are the same, but the type signatures are not).  However, I would
appreciate the communities advice on a few matters:

1) How should I name the kind * versions?  For example, the kind *
version of Functor is currently called Mappable with a class method of
rigidMap.  What should I call the kind * version of Foldable and its
corresponding methods?  Is there a valid system I can use for these?

You could prefix (or postfix) classes with an 'R' similar to RMonad, but that would conflict with the rmonad package.  For just Foldable, maybe Reduceable?

Do you have a kind * implementation of Foldable?  I'd be interested in seeing it, because I was unable to create a usable implementation (based upon the RMonad scheme) on my last attempt.
 

2) How far should I go?  Should I restrict myself to the
"data-oriented" classes such as Functor, Traversable, etc. or should I
try to make restricted versions of Applicative and Monad?  Assuming I
should:

I don't have a strong opinion either way, but could you re-use RMonad and RFunctor from the rmonad package?
 
2c) Should I keep the classes as-is, or should I explicitly put in the
constraints mentioned in the Typeclassopedia (e.g. make Applicative an
explicit superclass of Monad, and define return = pure for
compatability reasons)?  If so, should I bring over Pointed, etc. from
category-extras to round out the set or just stick with classes that
are already in base?

+1 for using the proper constraints, and especially for bringing over Pointed (and anything else that applies).
 

3) Am I wasting my time with this?
 
I would find it useful, and I appreciate all the care you're putting into the design.

Cheers,
John