
On Wed, Feb 16, 2011 at 7:01 AM, Ross Paterson
On Tue, Feb 15, 2011 at 07:46:29PM -0800, Evan Laforge wrote:
Do I really have to add (Functor m) to the 300 or so functions with (Monad m) on them? Or just not use fmap or applicative?
If you're using Monad m to get Functor or Applicative instances for a functor built from m, then I'm afraid you will need to add (Functor m) or (Applicative m) to the constraints in most cases.
I've noticed another solution, which is to make a class M with Applicative and Monad as superclasses, and put the lifted basic operations into that, then instead of '(Functor m, Monad m) => MyM m a', write '(M m) => m a'. I already do this same thing in a different place so I can get unlifted access from another transformer stack. It makes nicer looking signatures, but it's more complicated and less direct. Whenever it comes time to play games like that I have to do a fair amount of trial and error because I don't understand typeclasses or the type errors produced to get it right the first time. And I suppose if I can barely write it, I shouldn't, but I know other people understand this stuff a lot better than I do. Are other people using tricks like this? Or will there just be massive signature rewriting in the wake of mtl2? Or maybe others don't use monads so extensively?