F#部分应用第二个参数

时间:2018-08-07 15:34:51

标签: f# functional-programming currying partial-application

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

4 个答案:

答案 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
相关问题