## Additions to Control.Monad

I'd like to propose the following additions/changes to Control.Monad:
`mfilter`

can be generalised:

```
gen_mfilter :: Monad m => (a -> m ()) -> m a -> m a
gen_mfilter f ma = (\a -> liftM (const a) (f a)) =<< ma
```

Now we obtain the old `mfilter`

as

`gen_mfilter.(guard.)`

Further, `m ()`

is a monoid for every monad, which would cause conflicts for `[()]`

, to name one example. (The usual monoid instance of `[()]`

is addition of natural numbers, while the monadic monoid instance is multiplication.) More generally, the monoid `m ()`

acts on every type `m a`

in the following way:

```
mtimes :: Monad m => m () -> m a -> m a
mtimes = gen_mfilter.const = liftM2 (flip const)
when = mtimes.guard
```

For example, each element of a list can be duplicated like this:

`mtimes [(),()]`

To see why these functions are useful, consider the `DDist`

monad of the ProbabilityMonads package: Since `DDist ()`

is essentially the monoid of real numbers with multiplication, `gen_mfilter f`

updates a distribution by multiplying the weight of `x`

by `f x`

.
Another example is the state monad `ST s`

, where type `(a -> ST s ())`

is essentially `a -> s -> s`

, so these functions encode changes that, when used with `gen_mfilter`

alter state, not the value.

## Trac metadata

Trac field | Value |
---|---|

Version | 7.8.2 |

Type | FeatureRequest |

TypeOfFailure | OtherFailure |

Priority | low |

Resolution | Unresolved |

Component | libraries/base |

Test case | |

Differential revisions | |

BlockedBy | |

Related | |

Blocking | |

CC | ekmett, hvr |

Operating system | |

Architecture |