3
votes

I can obtain the even numbers in a list using the lambda syntax:

[1..10] |> List.filter (fun x -> x % 2 = 0)

But I want get it with composition, like this:

[1..10] |> List.filter ((% 2) >> (= 0))

Error: stdin(7,37): error FS0010: Unexpected integer literal in expression. Expected ')' or other token.

1

1 Answers

7
votes

F# does not support operator sections. You can partially apply an operator by enclosing it in parentheses, like so:

let five = (+) 2 3
let add2 = (+) 2
let alsoFive = add2 3

However, this will not allow you to partially apply the right argument of the operator. In other words, F# does not offer anything equivalent to Haskell expression (/ 2). This can be worked around for commutative operators, such as addition or multiplication, because (+ 2) === (2 +), which in F# can be expressed as ((+) 2), but not for non-commutative ones.

The best you can do is declare the section as a separate function, like this:

let mod2 x = x % 2
[1..10] |> List.filter (mod2 >> ((=) 0))

If you absolutely insist on not declaring any more functions, you could try to do with a flip:

[1..10] |> List.filter ((flip (%) 2) >> ((=) 0))

But sadly, F# standard library does not provide a flip function either, so you'd have to declare it yourself anyway:

let inline flip f a b = f b a

Personally, I would rather go for increased readability and declare an isEven function:

let isEven x = (x % 2) = 0
[1..10] |> List.filter isEven