Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my predicate being interpreted as a boolean? (Haskell)

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.

like image 904
fabikaktus Avatar asked Dec 22 '25 10:12

fabikaktus


2 Answers

(==) 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.

like image 153
Leif Metcalf Avatar answered Dec 24 '25 04:12

Leif Metcalf


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.)

like image 20
MathematicalOrchid Avatar answered Dec 24 '25 05:12

MathematicalOrchid



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!