如何以紧凑的方式避免意外的部分应用?
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,请在项目文件中手动编辑设置,如所述。
我有一个副作用函数,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,请在项目文件中手动编辑设置,如