Difference between revisions of "Functor hierarchy proposal"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
− | Currently the standard libraries include a < |
+ | 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 |
|
− | + | 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 |
|
+ | </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 |
||
⚫ | |||
− | 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.