Add mfilter to Control.Monad
authorjon.fairbairn@cl.cam.ac.uk <unknown>
Thu, 17 Sep 2009 14:56:16 +0000 (14:56 +0000)
committerjon.fairbairn@cl.cam.ac.uk <unknown>
Thu, 17 Sep 2009 14:56:16 +0000 (14:56 +0000)
Straightforward MonadPlus version of List.filter. I would
prefer to call it filter, but the current naming scheme for
Control.Monad implies mfilter.

Control/Monad.hs

index 5b46f8f..bf94ad4 100644 (file)
@@ -46,6 +46,7 @@ module Control.Monad
 
     , join          -- :: (Monad m) => m (m a) -> m a
     , msum          -- :: (MonadPlus m) => [m a] -> m a
+    , mfilter       -- :: (MonadPlus m) => (a -> Bool) -> m a -> m a
     , filterM       -- :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
     , mapAndUnzipM  -- :: (Monad m) => (a -> m (b,c)) -> [a] -> m ([b], [c])
     , zipWithM      -- :: (Monad m) => (a -> b -> m c) -> [a] -> [b] -> m [c]
@@ -311,6 +312,20 @@ ap                :: (Monad m) => m (a -> b) -> m a -> m b
 ap                =  liftM2 id
 
 
+-- -----------------------------------------------------------------------------
+-- Other MonadPlus functions
+
+-- | Direct 'MonadPlus' equivalent of 'filter'
+-- @'filter'@ = @(mfilter:: (a -> Bool) -> [a] -> [a]@
+-- applicable to any 'MonadPlus', for example
+-- @mfilter odd (Just 1) == Just 1@
+-- @mfilter odd (Just 2) == Nothing@
+
+mfilter :: (MonadPlus m) => (a -> Bool) -> m a -> m a
+mfilter p ma = do
+  a <- ma
+  if p a then return a else mzero
+
 {- $naming
 
 The functions in this library use the following naming conventions: