Joining predicates with logical && in filter function

Viewed 174

I just stumbled upon this sentence at learnyouahaskell.com:

The filter equivalent of applying several predicates in a list comprehension is either filtering something several times or joining the predicates with the logical && function.

Could someone give an example for the last part (joining the predicates with the logical && function)?

Does the author mean something like this (which doesn't work):

filter ((>3) && (<10)) [5,3]
2 Answers

filter's predicate argument is a function, so you would need to use a lambda:

filter (\x -> x > 3 && x < 10) [5,3]

I suppose the author was assuming the reader would do the appropriate expansion.

It's also possible to lift boolean operators to operate on predicates using the (a ->) Applicative instance:

filter (liftA2 (&&) (> 3) (< 10)) [5,3]

But I don't personally find that particularly nice.

Alternatively, instead of using a lambda abstraction (anonymous function), one can define the wanted filter predicate using let or where, giving that a name.

let inRange x = x > 3 && x < 10
in  filter inRange [5,3]

Using a lambda can be more convenient when the predicate is short, as in this case. On the other hand, giving the predicate a name can help make the code more readable, clarifying the intent.

Related