F#中部分应用的两种方式的区别

3
假设我们有以下函数(函数体并不重要):
let writelogf greeting x = 
    Printf.printf "%A" greeting
    Printf.printf "%A" x

这个函数的类型是'a -> 'b -> unit,这正是我想要的。
现在我定义一个部分应用的函数:
let logf x = writelogf "Hello!" x

这个函数的类型是'a -> unit,这正是我所期望的。我可以使用任何类型的参数来调用它:

logf "Test"
logf 1

但如果我试图简化声明并重复调用:
let logf2 = writelogf "Hello!"
logf2 "Test"
logf2 1

由于logf2不再是泛型,而是具有类型string -> unit(从第一次使用推断出来),所以它将不再编译。

为什么会这样呢?如果我有一个具有5个参数的函数并且我需要部分应用其中一个参数,我是否必须重复另外4个参数呢?


1
根据您的目标,let inline … 也可能是一种解决方案。 - Be Brave Be Like Ukraine
@bytebuster inline需要有一个函数,而不是一个值;而且如果有一个函数,问题已经“解决”了,无论是否使用inline。 - Sehnsucht
1个回答

3
在您编写了以下内容的情况下:

let logf2 = writelogf "Hello!"

您实际上绑定了一个通用类型的值。如果您将其定义更改为函数,例如通过显式地取参数或单位类型的参数,您可以解决此问题。

let logf x = writelogf "Hello!" x

let logf2() = writelogf "Hello!"

如果您有一个带有5个参数的函数,并且您部分应用了其中一个参数,那么您需要至少显式地传递一个参数,但您不需要重复另外3个参数。
let test5 a b c d e =
    printfn "%A" (a, b, c, d, e)

let testApplyOne x = test5 "Hello!" x

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接