在F#中是否可以讨论中间函数参数?

Vag*_*lov 7 f# currying

这里的代码工作正常:

let f x y z = x + y + z

let g x y = f x y
let h x z = z |> f x
Run Code Online (Sandbox Code Playgroud)

所以我可以写表达式"h 1",并且FSI显示:

val it : (int -> int -> int) = <fun:it@110-3>
Run Code Online (Sandbox Code Playgroud)

如果我调用"h 1 2 3",则以正确的顺序应用参数.
但如果最后一个参数具有不同的类型,则情况会有所不同:

let ff x y (z : string) = x + y

let gg x y = ff x y
let hh x (z : string) = z |> ff x
Run Code Online (Sandbox Code Playgroud)

现在最后一个函数hh会导致错误信息:

Script.fsx(119,10):错误FS0001:类型不匹配.期待string -> 'a 但是给了一个int -> string -> int.类型string与类型不匹配int

我理解为什么会发生这种情况 - "z"被附加到"ff x",使其成为第二个参数.但是我希望在第一个例子中表达式"h 1 2 3"不能正常工作(被执行为"f 1 3 2").但它的工作正常.

Tom*_*cek 8

函数ffgg示例中的函数相同 - 流水线操作符为右侧的函数的第一个参数提供值.在您的示例中,右侧的函数是ff x,通过使用流水线操作符,您可以指定参数的值y:

let ff x y (z : string) = 
  printfn "%s" z
  x + y

// These two functions are the same:
let gg x y = ff x y
let hh x y = y |> ff x
Run Code Online (Sandbox Code Playgroud)

使用部分函数应用程序时,没有stnadard语法用于指定除第一个参数之外的其他参数.但是,您可以编写高阶函数或自定义运算符来执行此操作.例如:

// Takes a function 'f' of type 'b -> 'a -> 'c
// and a value 'v' of type 'a and creates a function
// that takes the first argument ('b -> 'c)
let (|*>) v f = (fun mid -> f mid v);;

let gg x y = ff x y     // Specifies arguments x and y
let hh x z = z |*> ff x // Specifies arguments x and z
Run Code Online (Sandbox Code Playgroud)

我将运算符命名|*>为表示它跳过一个参数.您可以定义类似于指定其他参数值的运算符(例如|**>,跳过前两个参数).