## A handy generalized filter

For quite a while, I’ve been using a handy operation for filtering functional events:

justE :: Event (Maybe a) -> Event a

The idea of `justE`

is to drop the `Nothing`

-valued occurrences and strip off the `Just`

constructors from the remaining occurrences. Recently I finally noticed the similarity with a standard function (in `Data.Maybe`

):

catMaybes :: [Maybe a] -> [a]

I asked on #haskell about a common generalization, and oerjan offered the following:

I like this name and definition very much, including the use of `mzero`

and `return`

for empty and singleton monadic values, respectively. I particularly like how it works out for lists and events. Each element is passed into `maybe mzero return`

, so that a `Nothing`

becomes empty (`mzero`

), while a `Just x`

becomes a singleton (`return x`

).

I also like how `joinMaybes`

specializes easily into traditional, predicate-based filtering, generalizing the standard `filter`

function on lists:

filterMP :: MonadPlus m => (a -> Bool) -> m a -> m a filterMP p m = joinMaybes (liftM f m) where f a | p a = Just a | otherwise = Nothing

So it’s easy to define `filterMP`

in terms of `joinMaybes`

(and hence `filter`

in terms of `catMaybes`

). What about the reverse? Here’s one go at it:

filterMP' :: MonadPlus m => (a -> Bool) -> m a -> m a filterMP' p = (>>= f) where f a | p a = return a | otherwise = mzero joinMaybes' :: MonadPlus m => m (Maybe a) -> m a joinMaybes' = liftM fromJust . filterMP' isJust

Comparable simplicity, but I don’t like the `isJust`

and `fromJust`

. Not only is there some redundant checking, but the `fromJust`

function is partial, and so this definition is not so obviously total to an automated checker like Catch.

*Edit 2008-02-08*: added a “Continue reading …” token, to keep my blog’s front page uncluttered.

## Neil Mitchell:

Conal, Catch would happily accept the above definition as total and spot that the filter guarantees the Just property – its trivial for Catch. As an added bonus, Supero would optimise out the redundant Just matches, giving you something maximally efficient.

The moral of the story is just code simple, and I’ll come round later and take care of it!

26 January 2008, 2:35 am## Neil Mitchell:

I’ve also written some more about it at http://neilmitchell.blogspot.com/2008/01/safety-and-optimisation-joinmaybes.html

26 January 2008, 7:55 am## conal:

That’s terrific, Neil. Good stuff!

26 January 2008, 10:21 am## Conal Elliott » Blog Archive » Invasion of the composable Mutant-Bots:

[...] About « A handy generalized filter [...]

5 February 2008, 10:23 pm