Another feature of list comprehensions is guards, which also act as filters. Guards are Boolean expressions and appear on the right side of the bar in a list comprehension.
Their most basic use is
[x | p x] === if p x then [x] else []
Any variable used in a guard must appear on its left in the comprehension, or otherwise be in scope. So,
[ f x | x <- list, pred1 x y, pred2 x] -- `y` must be defined in outer scope
which is equivalent to
map f (filter pred2 (filter (\x -> pred1 x y) list)) -- or,
-- ($ list) (filter (`pred1` y) >>> filter pred2 >>> map f)
-- list >>= (\x-> [x | pred1 x y]) >>= (\x-> [x | pred2 x]) >>= (\x -> [f x])
(the >>=
operator is infixl 1
, i.e. it associates (is parenthesized) to the left). Examples:
[ x | x <- [1..4], even x] -- [2,4]
[ x^2 + 1 | x <- [1..100], even x ] -- map (\x -> x^2 + 1) (filter even [1..100])