如何以紧凑的方式避免意外的部分应用?

How can I avoid accidental partial application in a compact way?

我有一个副作用函数,f : int -> string -> unit,我使用 f 1 "hi" 调用它。

为了确保在函数更改为需要更多参数时我在调用站点中收到错误,我使用 () = f 1 "hi" |> ignore 调用该函数。如果函数被部分应用并且不会执行任何副作用,这将确保类型错误。

是否有更优雅的方法来避免意外的部分应用?

在最后添加一个"guard"参数:

let f a b c () = ...

并在调用点传递:

f 42 "foo" 3.14 ()

如果你添加另一个参数,它的类型将不匹配 unit(除非你要添加一个 unit 参数,但你为什么要这样做?),编译器会报错在呼叫站点。

额外的 unit 参数是表示仅具有副作用的函数的常用方法。

另一方面,对于纯函数,不需要这个技巧,因为你会对它们的 return 值感兴趣,而意外的部分应用会改变它的类型,导致编译器报错.

我只想添加类型注释

f 1 "hi" : unit

就是这样。

您从编译器收到的警告是 FS0193:"This expression is a function value, i.e. is missing arguments."

在 Visual Studio 中,在项目属性中,在将警告视为错误、特定警告中添加 0193。如果需要,请使用分号作为分隔符。

我看不出还有什么比这更优雅的了。源代码看起来和预期的一样,没有任何神秘感,但如果您修改函数而不同时调整调用站点,编译将失败。事实上,我不明白为什么默认情况下此警告不是错误。

如果您不使用 VS,请在项目文件中手动编辑设置,如所述。