F# 接口中的元组参数
有人能解释这种好奇心吗F# 接口中的元组参数,f#,F#,有人能解释这种好奇心吗 type IFoo = abstract member Bar1: int * int -> int * int abstract member Bar2: int * int -> (int * int) abstract member Bar3: (int * int) -> int * int type Foo() = class end with
type IFoo =
abstract member Bar1: int * int -> int * int
abstract member Bar2: int * int -> (int * int)
abstract member Bar3: (int * int) -> int * int
type Foo() = class end
with
interface IFoo with
member this.Bar1 (x, y) = (x, y)
member this.Bar2 (x, y) = (x, y) // Same impl as Bar1 i.e. parentheses on RHS of -> in interface member definition are ignored
// member this.Bar3 (x, y) = (x, y) // Compile error: "This override takes a different number of arguments to the corresponding abstract member"
member this.Bar3 tuple = tuple // So, parentheses on LHS of -> in interface member definition *does* make a difference!
IFoo.Bar1
和IFoo.Bar3
的定义在含义上有什么区别?在这里,输入类型可以描述两种不同的东西:元组或CLI方法的参数列表
这对返回类型没有影响,因为这个返回类型的唯一解释是元组。但是在参数列表中,您可以选择一个接受两个参数的CLI方法,或者一个接受一个参数的CLI方法,这恰好是一个元组。后者由附加括号表示
这就是为什么您可以用一个单独的参数实现Bar3,以元组的形式键入,这在其他参数中是不可能的(从F#3开始)
这也是双括号与单括号不同的地方。如果Bar3不是抽象的,您可以通过将其声明为成员this.Bar3((arg1,arg2))
来强制元组输入
方法参数列表具有其他功能,例如可选参数。因此:
type Test () =
member t.BarA(a, ?b) = a
member t.BarT((a, ?b)) = a // Error
最后一行给出错误“仅允许在类型成员上使用可选参数”,因为
b
现在是元组模式的一部分,而不是方法参数列表中的参数。有趣-CLI详细信息正在泄漏到F#语法中。我猜这是必要的互操作的原因?对于纯F#代码,我看不出有任何理由区分这两种情况。@Akash不管为什么,CLI方法的世界已经成为F#作为一种多范式语言的一部分。它有重载、继承和重写、可选参数等等,这些特性并不像null那样被认为是互操作的专有特性。但它们并不总是与函数优先编程很好地结合。在纯功能代码中,这些特性没有被使用,因此功能部分很好地映射到CLI方法——除了您的问题中显示的罕见的尴尬。