Difference between revisions of "Functor hierarchy proposal"

From HaskellWiki
Jump to navigation Jump to search
Line 1: Line 1:
Currently the standard libraries include a <tt>[[Functor]]</tt> class and a <tt>[[Monad]]</tt> class, and <tt>Functor</tt> is not a superclass of <tt>Monad</tt>, even though logically every monad is a functor. Various schemes have been proposed to create a richer hierarchy of Functor classes. Here's a typical example:
+
Currently the standard libraries include a <hask>Functor</hask> class and a <hask>Monad</hask> class, and <hask>Functor</hask> is not a superclass of <hask>Monad</hask>, even though logically every monad is a functor. New classes have been added to HEAD to create a richer hierarchy of Functor classes:
   
  +
<haskell>
class Functor f where
+
class Functor f where
fmap :: (a -> b) -> f a -> f b
+
fmap :: (a -> b) -> f a -> f b
   
class (Functor f) => Idiom f where
+
class Functor f => Applicative f where
ap :: f (a -> b) -> f a -> f b
+
pure :: a -> f a
return :: a -> f a
+
(<*>) :: f (a -> b) -> f a -> f b
   
  +
(*>) :: Applicative f => f a -> f b -> f b
class (Idiom f) => Monad f where
 
(>>=) :: f a -> (a -> f b) -> f b
+
fa *> fb = (fmap (const id) fa) <*> fb
  +
</haskell>
   
  +
I propose that "<hask>pure</hask>" be renamed "<hask>return</hask>", "<hask>*></hask>" be renamed "<hask>>></hask>", and that <hask>Monad</hask> be made a subclass of <hask>Applicative</hask>:
satisfying the usual Functor and Monad laws, and
 
   
  +
<haskell>
fmap = ap . return
 
 
class (Applicative f) => Monad f where
ap fab fa = fab >>= (\ab -> fmap ab fa)
 
  +
(>>=) :: f a -> (a -> f b) -> f b
:(and others)
 
  +
</haskell>
   
 
The downside of this is that every instance declaration of <tt>Monad</tt> would have to be accompanied by instance declarations for the superclasses.
 
The downside of this is that every instance declaration of <tt>Monad</tt> would have to be accompanied by instance declarations for the superclasses.

Revision as of 07:02, 25 April 2006

Currently the standard libraries include a Functor class and a Monad class, and Functor is not a superclass of Monad, even though logically every monad is a functor. New classes have been added to HEAD to create a richer hierarchy of Functor classes:

class Functor f where
  fmap :: (a -> b) -> f a -> f b

class Functor f => Applicative f where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

(*>) :: Applicative f => f a -> f b -> f b
  fa *> fb = (fmap (const id) fa) <*> fb

I propose that "pure" be renamed "return", "*>" be renamed ">>", and that Monad be made a subclass of Applicative:

class (Applicative f) => Monad f where
  (>>=) :: f a -> (a -> f b) -> f b

The downside of this is that every instance declaration of Monad would have to be accompanied by instance declarations for the superclasses.