Moritz Schmidt
Moritz Schmidt

Reputation: 2813

Haskell - Filter, Currying

I just want to know if my following understanding about currying functions is correct. I want to filter all elements from a list which are > 4. I can achieve this like so:

filter (>4) [1..10]
  1. (>) is defined as Ord a => a -> a -> Bool, thats why it cant be bassed to filter.
  2. (>4) is defined as (Ord a, Num a) => a -> Bool. The function (>) is now curried and still expects one parameter.
  3. Because of 2., (>4) can be passed to filter.
  4. Every List-Element, which is passed to filter, will be passed to (>4) and and filter will validate the predicate and return the result.

Is this correct?

Upvotes: 2

Views: 258

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476584

The reasoning is more or less correct. (>) is a function with signature:

(>) :: Ord a => a -> (a -> Bool)

so it is a function that (like any other function in Haskell) takes one parameter, and here returns a function a -> Bool.

The problem is thus that if we would use filter (>) [1,4,2,5], then we would make a call (>) 1, and this would thus return a function a -> Bool, but a filter can not work with that, it requires a function that takes an element from the list, and returns a Bool, not a function that returns a function that maps to a Bool.

We thus can for example use:

filter ((<) 4) [1,4,2,5]

Here we thus perform partial application [Haskell-wiki] of the function. This thus means that we generate a function (<) 4 :: (Num a, Ord a) => a -> Bool. We thus can filter with that function, it will thus return [5].

We can also make a function with a lambda expression to "swap" the order of the parameters:

filter (\x -> (>) x 4) [1,4,2,5]

Here for a value x, we will thus call ((>) x) 4, and this will thus return a Bool.

Since it happens often that one of the two sides of an infix operator is provided a value, Haskell has sectioning syntax for an infix operator [Haskell-wiki]:

  • (2^) (left section) is equivalent to (^) 2, or more verbosely \x -> 2 ^ x;
  • (^2) (right section) is equivalent to flip (^) 2, or more verbosely \x -> x ^ 2

So we can rewrite the last expression to:

filter (> 4) [1,4,2,5]

Upvotes: 2

Related Questions