
On 23 March 2005 15:51, Ross Paterson wrote:
On Wed, Mar 23, 2005 at 09:49:43AM -0000, Simon Marlow wrote:
Does anyone else have any comments on the suggestions from Iavor and Thomas in this thread? I'm happy to make changes, but only if there's a concensus. The proposals so far seems to be
1) add dist method 2a) make Functor a superclass of FunctorM 2b) make Functor a *sub*class of FunctorM 2c) make Functor a subclass of Monad 2d) make Functor a superclass of Monad 3) rename FunctorM class to ForEach 4) rename FunctorM module to Control.Monad.FunctorM(?)
(1) is easy and not controversial (but is 'dist' the best name?).
fsequence:sequence = fmapM:mapM = fmap:map ?
As long as we remember that it's not always a distributive law (join law fails, e.g. for []), and fmapM doesn't always define a functor (doesn't preserve composition of Kleisli arrows).
2a) is needed to provide the default definition
fmapM f = fsequence . fmap f
The options are now boiled down a bit: 1) FunctorM remains as it is, and we add fsequence :: (Monad m, FunctorM f) => f (m a) -> m (f a) (John Meacham's suggestion) 2) class Functor f => FunctorM f where fsequence :: Monad m => f (m a) -> m (f a) fmapM :: Monad m => (a -> m a) -> f a -> m (f a) fsequence = fmapM id fmapM f = fsequence . fmap f the difference is quite small, mainly an efficiency tradeoff, but also if defining fsequence is easier than fmapM you might prefer (2).
The placement in the hierarchy is a bit wierd. Another possibility (that you suggested earlier) is Data.Functor.
Data.Functor would export both Functor and FunctorM? Cheers, Simon