Ily*_*mov 5 f# functional-programming currying partial-application
在F#中如果我接受一个带有两个参数的函数,例如,mod(%):
13 % 10
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
这是一样的
(%) 13 10
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
是否有任何方法可以用管道符号写出来,把13?
显然,"双参数函数"实际上是一个返回中间函数的单参数函数.管道也可以
10 |> (%) 13
// val it : int = 3
Run Code Online (Sandbox Code Playgroud)
但是,我需要另一种方法,即管道第一个参数13,第二个参数10部分应用,但不是第一个参数.
语言中是否有任何有助于这样做的东西,而不是每次都创建额外的lambdas,即避免以下情况?
13 |> (fun x -> x % 10)
Run Code Online (Sandbox Code Playgroud)
没有内置的标准方法来执行此操作.此外,由于函数应用程序的工作原理,不可能这样做:只要你编写(%) 13,你就已经应用了第一个参数,因为函数应用程序在F#中具有最高且不可配置的优先级.
你可以,如果当然,让自己的特殊功能,以产生"怪异"的功能应用 - 一个将应用于第二个参数,离开第一个孔:
let ap f x = fun y -> f y x
Run Code Online (Sandbox Code Playgroud)
然后:
let x = 13 |> ap (%) 10
> x : int = 3
Run Code Online (Sandbox Code Playgroud)
顺便提一下,这个函数ap在ML语言中是半标准的,并且通常被称为flip,因为它所做的是"翻转"参数的顺序:
let flip f x y = f y x
Run Code Online (Sandbox Code Playgroud)
或者,您甚至可以将其变为运营商:
let (-*-) = flip
Run Code Online (Sandbox Code Playgroud)
然后:
let x = 13 |> (%) -*- 10
> x : int = 3
Run Code Online (Sandbox Code Playgroud)
然而,这种欺骗很快就变得难以理解.在实践中,仅仅声明一个能够满足您需求的函数更为可取:
let mod10 x = x % 10
Run Code Online (Sandbox Code Playgroud)
然后:
let x = 13 |> mod10
Run Code Online (Sandbox Code Playgroud)
或者,如果你真的需要它非常一般:
let mod' x y = y % x
Run Code Online (Sandbox Code Playgroud)
然后:
let x = 13 |> mod' 10
Run Code Online (Sandbox Code Playgroud)