Hi, I was thinking lately about the well known problem that Monad is neither Functor nor Applicative. As I understand, it is caused by some historical issues. What I like about Haskell is that it allows to describe very nicely what different objects actually are - something that I find very important for programming. And this issue violates this principle.
This has been discussed here more than year ago in http://www.haskell.org/pipermail/haskell-prime/2011-January/003312.html : On 1/4/11 11:24, oleg at okmij.org wrote: > I'd like to argue in opposition of making Functor a super-class of > Monad. I would argue that superclass constraints are not the right > tool for expressing mathematical relationship such that all monads are > functors and applicatives. > > Then argument is practical. It seems that making Functor a superclass > of Monad makes defining new monad instances more of a chore, leading > to code duplication. To me, code duplication is a sign that an > abstraction is missing or misused. > ... The main objections were that it would break existing code and that it would lead to code duplication. The former is serious, the second can be easily solved by standard Haskell, since one can define instance Applicative ... where pure = return (<*>) = ap instance Functor ... where fmap = liftM To address the first objection: AFAIK nobody mentioned the "Default superclass instances" proposal: http://hackage.haskell.org/trac/ghc/wiki/DefaultSuperclassInstances To give an example how it would work: 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 says that if somebody defines an instance of Monad it automatically becomes an instance of Applicative as defined in the nested "instance" block. So there is no need to define Applicative/Functor explicitly, making existing code work. Implementing this proposal would allow making Monad to extend Functor and Applicative without breaking existing code. Moreover, this would simplify other things, for example it would be possible to define an instance of Traversable and the instances for Functor and Foldable would be defined implicitly using fmapDefault and foldMapDefault. I'm sure there are many other cases where splitting type classes into a more fine-grained hierarchy would be beneficial, and the main reason against it is simply not to break compatibility with existing code. IMHO this would be worthwhile to consider for some future revision of Haskell. Best regards, Petr Pudlak _______________________________________________ Haskell-prime mailing list Haskell-prime@haskell.org http://www.haskell.org/mailman/listinfo/haskell-prime