# Difference between revisions of "MonadPlus reform proposal"

From HaskellWiki

BrettGiles (talk | contribs) m (Adding category) |
Nmessenger (talk | contribs) m (added pretty colors!) |
||

Line 7: | Line 7: | ||

=== MonadZero === | === MonadZero === | ||

− | + | <haskell> | |

− | + | class Monad m => MonadZero m where | |

+ | mzero :: m a | ||

+ | </haskell> | ||

satisfying '''Left Zero''': | satisfying '''Left Zero''': | ||

− | + | ||

+ | <haskell> | ||

+ | mzero >>= k = mzero | ||

+ | </haskell> | ||

=== MonadPlus === | === MonadPlus === | ||

− | + | <haskell> | |

− | + | class MonadZero m => MonadPlus m where | |

+ | mplus :: m a -> m a -> m a | ||

+ | </haskell> | ||

satisfying '''Monoid''' and '''Left Distribution''': | satisfying '''Monoid''' and '''Left Distribution''': | ||

− | + | ||

− | + | <haskell> | |

− | + | mplus mzero b = b | |

− | + | mplus a mzero = a | |

+ | mplus (mplus a b) c = mplus a (mplus b c) | ||

+ | mplus a b >>= k = mplus (a >>= k) (b >>= k) | ||

+ | </haskell> | ||

=== MonadOr === | === MonadOr === | ||

− | + | <haskell> | |

− | + | class MonadZero m => MonadOr m where | |

+ | morelse :: m a -> m a -> m a | ||

+ | </haskell> | ||

satisfying '''Monoid''' and '''Left Catch''': | satisfying '''Monoid''' and '''Left Catch''': | ||

− | + | ||

− | + | <haskell> | |

− | + | morelse mzero b = b | |

− | + | morelse a mzero = a | |

+ | morelse (morelse a b) c = morelse a (morelse b c) | ||

+ | morelse (return a) b = return a | ||

+ | </haskell> | ||

== Instances of both == | == Instances of both == | ||

Line 39: | Line 54: | ||

Some types could be made instances of both. For instance: | Some types could be made instances of both. For instance: | ||

− | + | <haskell> | |

+ | instance MonadOr [] where | ||

morelse [] b = b | morelse [] b = b | ||

morelse a b = a | morelse a b = a | ||

+ | </haskell> | ||

[[Category:Proposals]] [[Category:Monad]] | [[Category:Proposals]] [[Category:Monad]] |

## Revision as of 00:26, 4 January 2007

The MonadPlus class is ambiguous: while all instances satisfy **Monoid** and **Left Zero**, some such as `[]` satisfy **Left Distribution**, while others such as `Maybe` and `IO` satisfy **Left Catch**.

## Proposal

It is proposed that MonadPlus be split like this:

### MonadZero

```
class Monad m => MonadZero m where
mzero :: m a
```

satisfying **Left Zero**:

```
mzero >>= k = mzero
```

### MonadPlus

```
class MonadZero m => MonadPlus m where
mplus :: m a -> m a -> m a
```

satisfying **Monoid** and **Left Distribution**:

```
mplus mzero b = b
mplus a mzero = a
mplus (mplus a b) c = mplus a (mplus b c)
mplus a b >>= k = mplus (a >>= k) (b >>= k)
```

### MonadOr

```
class MonadZero m => MonadOr m where
morelse :: m a -> m a -> m a
```

satisfying **Monoid** and **Left Catch**:

```
morelse mzero b = b
morelse a mzero = a
morelse (morelse a b) c = morelse a (morelse b c)
morelse (return a) b = return a
```

## Instances of both

Some types could be made instances of both. For instance:

```
instance MonadOr [] where
morelse [] b = b
morelse a b = a
```