Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering with a predicate that takes 2 arguments

What I want would basically be a O(n^2) iteration over a list. Let's say I have a list of two integers,

let list = [2312, 8000, 3456, 7000, 1234]

and a function to check if adding two integers together would produce a result higher than 20000 (this could be an arbitrary function that takes two integers and returns a boolean).

myPredicate :: Int -> Int -> Bool
myPredicate x y = x + y > 10000

Is there a way to apply this predicate to the above list to get a list of lists that include valid pairs, like this:

>> filter myPredicate list
>> [[2312, 8000], [3456, 8000], [3456, 7000], [8000, 7000]]
like image 773
Sarp Başaraner Avatar asked Nov 19 '25 11:11

Sarp Başaraner


2 Answers

If I understood you correctly you want to construct the list of pairs,

pairs xs = [(y,z) | (y:ys) <- tails xs, z <- ys]

and then filter it out using your predicate which needs to be in uncurried form,

myPredicate' :: (Int,Int) -> Bool
myPredicate' x y = x + y > 10000

so,

filter myPredicate' (pairs list)

or equivalently

filter (uncurry myPredicate) (pairs list)
like image 109
Jorge Adriano Avatar answered Nov 21 '25 03:11

Jorge Adriano


This is supported by Haskell syntax directly.

[(x, y) | x <- myList, y <- myList, x + y > 20000]

This will return reversed and repeated pairs. If that's not what you need, consider these list comprehensions:

[(x, y) | x <- myList, y <- myList, x < y, x + y > 20000] -- no reversed pairs, no repeats

[(x, y) | x <- myList, y <- myList, x <= y, x + y > 20000] -- repeats, no reversed pairs

If for some reason unknown to science you have a list with duplicate elements, say [30000,30000] and you want only elements at different positions to form valid pairs, then this simple list comprehension won't work. I have no idea what kind of real life problem would require this, but here you are:

[(y,z) | (y:ys) <- tails xs, z <- ys, y + z > 20000]

(idea stolen from the other answer)

like image 20
n. 1.8e9-where's-my-share m. Avatar answered Nov 21 '25 04:11

n. 1.8e9-where's-my-share m.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!