Haskell chain filters

to write "map f (map g xs)" as one call to the map, you could write

Example xs = map (fg) xs

but how would you write "filter p (filter q xs)" as one call to filter? operator-point does not seem to work for the filter, as for maps. guess that you would use something else for predicates?

+6
filter haskell
source share
8 answers

If you defined a both function that looked like this:

 both :: (a -> Bool) -> (a -> Bool) -> a -> Bool both fgx = fx && gx 

Then you could write:

 example xs = filter (both pq) xs 

I'm not sure if there is a standard feature that does this for you ...

+9
source share
  $ ghci
 Prelude>: m + Control.Arrow
 Prelude Control.Arrow>: t uncurry (&&).  ((0 <) &&& (<10))
 uncurry (&&).  ((0 <) &&& (<10)) :: (Num a, Ord a) => a -> Bool
 Prelude Control.Arrow> filter (uncurry (&&). ((0 <) &&& (<10))) [0..15]
 [1,2,3,4,5,6,7,8,9]

Or declare your own operators if you do this often.

 infixr 3 &&: p &&: q = \a -> pa && qa infixr 2 ||: p ||: q = \a -> pa || qa not' = (.) not all' = foldr (&&:) $ const True any' = foldr (||:) $ const False example xs = filter (p &&: q ||: not' r) xs 
+8
source share

Why not understand the list?

 example = [x | x <- xs, px, qx] -- for example example = [x | x <- [1..10], (>3) x, x<5 ] -- [4] 
+6
source share

Calling a list of functions over something is essentially what the ap function does in Control.Monad. Then you simply and results. The only slight ugliness is that ap requires both of its arguments to be in the same monad (a list in this case), so we need to match it with return .

 import Control.Monad filterByMany funcs = filter (and . ap funcs . return) 
+4
source share

I would define a lambda expression.

 module Main where overTen :: Int -> Bool overTen = (>10) main :: IO () main = do print $ filter (\x -> overTen x && even x) [1..20] 

exit:

 $ ghci Test.hs GHCi, version 6.10.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. [1 of 1] Compiling Main ( Test.hs, interpreted ) Ok, modules loaded: Main. *Main> main [12,14,16,18,20] *Main> 
+4
source share
 import Data.Foldable import Data.Monoid p = (>4) g = (<10) main = print $ filter (getAll . foldMap (All.) [p,g]) [1..10] 

exits

 [5,6,7,8,9] 

just because lists are bent and you can combine predicate results with monoid All

+3
source share

Something like:

 example xs = filter (forAll [p,q,r,s,t,u,v]) xs forAll:: [(a -> Bool)] -> a -> Bool forAll funcs x = all (map ($ x) funcs) 
+2
source share

I would define a helper function - this could probably be written more declaratively, but I do not have GHCI installed on this system for testing:

 allPredicates :: [a -> Bool] -> a -> Bool allPredicates [] _ = True allPredicates (p:ps) x = px && allPredicates ps x 

then

 filter (allPredicates [p, q]) xs 
+1
source share

All Articles