在F#中,如果我接受一个带有两个参数的函数,例如mod(%):
13 % 10
// val it : int = 3
与
相同(%) 13 10
// val it : int = 3
有什么办法用管道符号将其写成13吗?
显然,“二参数函数”实际上是一个返回中间函数的单参数函数。管道也可以
10 |> (%) 13
// val it : int = 3
但是,我还需要另一种方法,即用管道传递第一个参数13,部分应用第二个参数10,而不是第一个参数。
是否有任何语言可以帮助您做到这一点,而不必每次都创建额外的lambda,即避免出现以下情况?
13 |> (fun x -> x % 10)
答案 0 :(得分:5)
没有内置的标准方法来执行此操作。而且,由于函数应用程序是如何工作的,因此无法做到这一点:一旦编写(%) 13
,就已经应用了第一个参数,因为函数应用程序在F#中具有最高且不可配置的优先级。 / p>
如果可以的话,您可以使自己成为一个特殊的函数,以产生一个“怪异的”函数应用程序-一个将应用第二个参数并为第一个参数留空的应用程序:
let ap f x = fun y -> f y x
然后:
let x = 13 |> ap (%) 10
> x : int = 3
偶然地,函数ap
在ML语言中是半标准出现,通常称为flip
,因为它的作用是“翻转”参数的顺序:
let flip f x y = f y x
或者,您甚至可以将其变成运算符:
let (-*-) = flip
然后:
let x = 13 |> (%) -*- 10
> x : int = 3
但是,这种欺骗手段很快就变得难以理解。实际上,最好只声明一个满足您需要的函数:
let mod10 x = x % 10
然后:
let x = 13 |> mod10
或者,如果您真的需要它非常笼统:
let mod' x y = y % x
然后:
let x = 13 |> mod' 10
答案 1 :(得分:2)
您可以编写一个组合器,该组合器将对两个参数的任何函数执行此操作:
let inline flip f y x = f x y
这可以用作:
13 |> flip (%) 10
答案 2 :(得分:1)
K,您正在寻找空翻
let flip f a b = f b a
答案 3 :(得分:1)
F#已经包含一个可以执行您想要的操作的运算符,即<|
:
10 |> (%) <| 13;;
val it : int = 10
这等效于
(10 |> (%)) 13;;
val it : int = 10