# Difference between revisions of "Functor hierarchy proposal"

(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.