1

tacit programming的一个想法是不能将参数应用于函数,如果可以避免的话。通过默认编程实现F#接口

如果函数是第一类成员,为什么F#不允许这样编译?

type IAdder = 
    interface 
    abstract member Add : int -> int -> int 
end 

type Adder = 
    interface IAdder with 
     member this.Add x y = x + y 

type AdderWithInnerAdder(adder:IAdder) = 
    interface IAdder with 
     member this.Add = adder.Add 

我得到的编译错误...

没有抽象属性发现,对应于这个覆盖

我觉得这应该编译。 adder.Add明确实施了IAdder.Add并且应该是可以接受的。

回答

2

您不能像接口函数那样分配接口成员。接口不能像那样工作。你必须指定参数:

member this.Add x y = adder.Add x y 

但接口通常是可以使用的。它们只适用于传递泛型函数而不会失去通用性。当函数是非泛型的时候,接口是严格低劣的。

如果你愿意与一个功能更强大的方式去代替,生活会得到易迅:

type Adder = { Add: int -> int -> int } 
let adder() = { Add = fun x y -> x + y } 
let adderWithInnerAdder adder = { Add = adder.Add } 
+1

我喜欢,有接近这一个功能更强大的方式。约束是我必须与用C#编写的代码进行互操作。感谢您的回答。 – t3dodson

+2

@ t3dodson如果您需要与C#进行互操作,那么在您的界面中也应该避免使用curried参数。在C#代码中使用'FSharpFunc's不会带来惯用的体验。 – TheInnerLight

+1

@TheInnerLight,他们只从F#一边看咖啡。成员函数和let-bound函数被编译为普通方法,而不考虑currying。 –