Reputation: 3932
in F# if I take a function that takes two arguments, for example, mod (%):
13 % 10
// val it : int = 3
which is the same as
(%) 13 10
// val it : int = 3
is there any way to write it in the pipe notation, currying the 13?
Obviously, the “two-argument function” is actually a one-argument function that returns an intermediate function. So can pipe
10 |> (%) 13
// val it : int = 3
However, I need the other way around, i.e. pipe the first argument 13, having the second argument 10 partially applied, but not the first one.
Is there anything in the language that helps to do that, without creating extra lambdas every time, i.e. to avoid the following?
13 |> (fun x -> x % 10)
Upvotes: 6
Views: 1471
Reputation: 4758
F# already contains an operator that will do what you want, namely <|
:
10 |> (%) <| 13;;
val it : int = 10
This is equivalent to
(10 |> (%)) 13;;
val it : int = 10
Upvotes: 2
Reputation: 80754
There is no built-in, standard way to do this. Moreover, due to how function application works, it's impossible to do so: as soon as you write (%) 13
, you've already applied the first argument, because function application has the highest and non-configurable precedence in F#.
You can, if course, make yourself a special function to produce a "weird" function application - one that would apply the second argument and leave a hole for the first:
let ap f x = fun y -> f y x
And then:
let x = 13 |> ap (%) 10
> x : int = 3
Incidentally, the function ap
is a semi-standard occurrence in ML languages, and is usually called flip
, because what it does is "flipping" the order of the arguments:
let flip f x y = f y x
Or, you can even make it into an operator:
let (-*-) = flip
And then:
let x = 13 |> (%) -*- 10
> x : int = 3
However, this sort of trickery gets unreadable very quickly. In practice, it is far more preferable to just declare a function that does what you need:
let mod10 x = x % 10
And then:
let x = 13 |> mod10
Or, if you really need it to be very general:
let mod' x y = y % x
And then:
let x = 13 |> mod' 10
Upvotes: 7
Reputation: 40623
You can write a combinator that will do this for any function of two arguments:
let inline flip f y x = f x y
This can be used as:
13 |> flip (%) 10
Upvotes: 4