Functor hierarchy proposal: Difference between revisions
(Category:Functor) |
Twhitehead (talk | contribs) (Note about the possibility of splitting off a Pointed class) |
||
Line 9: | Line 9: | ||
(<*>) :: f (a -> b) -> f a -> f b | (<*>) :: f (a -> b) -> f a -> f b | ||
(*>) :: Applicative f => f a -> f b -> f b | (*>) :: Applicative f => f a -> f b -> f b | ||
fa *> fb = (fmap (const id) fa) <*> fb | fa *> fb = (fmap (const id) fa) <*> fb | ||
</haskell> | </haskell> | ||
Line 21: | Line 21: | ||
The downside of this is that every instance declaration of <tt>Monad</tt> would have to be accompanied by instance declarations for the superclasses, but see [[Class system extension proposal]]. | The downside of this is that every instance declaration of <tt>Monad</tt> would have to be accompanied by instance declarations for the superclasses, but see [[Class system extension proposal]]. | ||
It might also be useful to split a <hask>Pointed</hask> class from the <hask>Applicative</hask> class. | |||
<haskell> | |||
class Pointed f where | |||
pure :: a -> f a | |||
class (Functor f, Pointed f) => Applicative f where | |||
(<*>) :: f (a -> b) -> f a -> f b | |||
(*>) :: Applicative f => f a -> f b -> f b | |||
fa *> fb = (fmap (const id) fa) <*> fb | |||
</haskell> | |||
Such <hask>Pointed</hask> functionality by itself could be useful, for example, in a DSL in which it is only possible to embed values and not to lift functions to functions over those embedded values. | |||
[[Category:Proposals]] | [[Category:Proposals]] | ||
[[Category:Functor]] | [[Category:Functor]] |
Revision as of 15:51, 7 December 2010
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, but see Class system extension proposal.
It might also be useful to split a Pointed
class from the Applicative
class.
class Pointed f where
pure :: a -> f a
class (Functor f, Pointed f) => Applicative f where
(<*>) :: f (a -> b) -> f a -> f b
(*>) :: Applicative f => f a -> f b -> f b
fa *> fb = (fmap (const id) fa) <*> fb
Such Pointed
functionality by itself could be useful, for example, in a DSL in which it is only possible to embed values and not to lift functions to functions over those embedded values.