id,summary,reporter,owner,description,type,status,priority,milestone,component,version,resolution,keywords,cc,os,architecture,failure,testcase,blockedby,blocking,related,differential,wikipage
9385,Additions to Control.Monad,olf,ekmett,"I'd like to propose the following additions/changes to Control.Monad:
`mfilter` can be generalised:
{{{#!hs
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
{{{#!hs
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:
{{{#!hs
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:
{{{#!hs
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.",feature request,closed,low,,Core Libraries,7.8.2,invalid,report-impact,hvr ekmett core-libraries-committee@…,Unknown/Multiple,Unknown/Multiple,None/Unknown,,,,,,