[commit: ghc] master: Make filterM a good consumer (96a4062)

git at git.haskell.org git at git.haskell.org
Wed Oct 1 16:21:44 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/96a4062a7e7587592829c045b3b12c755cc8e329/ghc

>---------------------------------------------------------------

commit 96a4062a7e7587592829c045b3b12c755cc8e329
Author: David Feuer <David.Feuer at gmail.com>
Date:   Wed Oct 1 15:59:39 2014 +0200

    Make filterM a good consumer
    
    analogously to mapM. Fixes #9546.


>---------------------------------------------------------------

96a4062a7e7587592829c045b3b12c755cc8e329
 libraries/base/Control/Monad.hs | 12 +++++++-----
 libraries/base/changelog.md     |  3 ++-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/libraries/base/Control/Monad.hs b/libraries/base/Control/Monad.hs
index 619a2ba..db46dea 100644
--- a/libraries/base/Control/Monad.hs
+++ b/libraries/base/Control/Monad.hs
@@ -93,12 +93,14 @@ guard False     =  empty
 
 -- | This generalizes the list-based 'filter' function.
 
+{-# INLINE filterM #-}
 filterM          :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
-filterM _ []     =  return []
-filterM p (x:xs) =  do
-   flg <- p x
-   ys  <- filterM p xs
-   return (if flg then x:ys else ys)
+filterM p        = foldr go (return [])
+  where
+    go x r = do
+      flg <- p x
+      ys <- r
+      return (if flg then x:ys else ys)
 
 infixr 1 <=<, >=>
 
diff --git a/libraries/base/changelog.md b/libraries/base/changelog.md
index 09b749a..f7d8b1c 100644
--- a/libraries/base/changelog.md
+++ b/libraries/base/changelog.md
@@ -77,7 +77,8 @@
     second argument, so that the fusion RULES for it do not change the
     semantics. (#9596)
 
-  * `scanr` and `mapAccumL` now take part in list fusion (#9355, #9502)
+  * `scanr`, `mapAccumL` and `filterM` now take part in list fusion (#9355,
+    #9502, #9546)
 
 ## 4.7.0.1  *Jul 2014*
 



More information about the ghc-commits mailing list