
On Thu, Nov 29, 2012 at 03:52:58AM +0100, Ben Franksen wrote:
Tony Morris wrote:
As a side note, I think a direct superclass of Functor for Monad is not a good idea, just sayin'
class Functor f where fmap :: (a -> b) -> f a -> f b
class Functor f => Apply f where (<*>) :: f (a -> b) -> f a -> f b
class Apply f => Bind f where (=<<) :: (a -> f b) -> f a -> f b
class Apply f => Applicative f where unit :: a -> f a
class (Applicative f, Bind f) => Monad f where
Same goes for Comonad (e.g. [] has (=<<) but not counit) ... and again for Monoid, Category, I could go on...
Hi Tony
even though I dismissed your mentioning this on the Haskell' list, I do have to admit that the proposal has a certain elegance. However, before I buy into this scheme, I'd like to see some striking examples for types with natural (or at least useful) Apply and Bind instances that cannot be made Applicative resp. Monad.
Try writing an Applicative instances for (Data.Map.Map k). It can't be done, but the Apply instance is (I would argue) both natural and useful.
Also, it is not clear to me what laws should hold for them.
http://hackage.haskell.org/package/semigroupoids defines all of these and specifies laws, presumably derived in a principled way. -Brent