I’m trying to use the find function on a list of pairs, and I want to find the first pair in which the first element equals x, so I wrote:
find (x == fst) list
Since the fst function lacks an argument, I thought (x == fst) would be a function that takes in a tuple and returns a boolean, but the compiler interprets it as a boolean, as if fst were a variable. Maybe fst is being interpreted as a function? But doesn’t that require it to be surrounded by ()?
I did solve the problem using a list comprehension instead but I’m still curious as how to one would solve it using find.
(==) has type x -> x -> Bool. In your case, type x is (a, b) -> a. This is because one of it's operands is fst, which has that type. Therefore, the type of (==) in your case is ((a, b) -> a) -> ((a, b) -> a) -> Bool. That is, (==) is a function that compares two functions, x and fst.
What you want is to compose fst and (==). For example, (\y -> (x == fst y). This is a function that takes a tuple, y, and checks if x is equal to its first value.
There is a function that composes functions for you, (.). It takes two functions, f(x) and g(x), and returns another function, f(g(x)). You can use this function for your program like this: find ((x ==) . fst) list.
Compare the following programs, the first written as a lambda function, the second with the function composition operator:
(\y -> (x == fst y)
-- Compared to:
(x ==) . fst
Summary:
(==) is comparing two functions, x and fst, and returning a Bool.
What you want instead is a function that takes in a tuple, gets the first item from it, and compares it to x. This can be done with function composition.
If you want to pass a variable into a particular position, use a lambda function:
(\ y -> x == fst y)
Otherwise the compiler has no idea exactly where you're hoping to insert a variable.
If your function calls one function, you can use currying to take a short cut. But for complex expressions, that doesn't work. You can't just leave off the last term in an expression and expect it to work. It only works for a single function.
The other alternative is to take the function (x ==) and the function fst and chain them with the (.) operator:
((x ==) . fst)
It's a matter of personal taste which is "better". (There is no performance difference; the only difference is what your source code looks like.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With