# MonadPlus reform proposal

Jump to navigation
Jump to search

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
```

## Discussion

Given that Control.Applicative(Alternative) now defines a class which seems innately bound to **Left Catch**, at least in spirit, it seems to make sense to clean up MonadPlus such that all instances obey **Left Distribution**? --sclv