为什么我不能在这里调用f
的base
实现:
type Base =
abstract f : int -> int -> int
default this.f (x : int) (y : int) : int = x + y
type Derived =
inherit Base
override this.f (x : int) (y : int) : int = base.f -x -y
调用base.f
会导致编译错误:
error FS0419: 'base' values may only be used to make direct calls to the base implementations of overridden members
如果我改变f
接受一个参数,然后它编译。据推测,这与curry参数和元组参数有关,但上面的代码对我来说看起来很好。
我认为问题是base
不能被闭包捕获-必须直接进行调用。但是,重写柯里化函数会自动创建闭包,因为只会立即应用第一个参数。因此,尽管看起来您确实使用base
值来直接调用被覆盖成员的基本实现,但实际上您在闭包中使用base
值,这是非法的。
不幸的是,我不认为有任何好的方法来解决这个问题。一般来说,您应该尽可能避免curry成员,但这里有一个替代方案:
type Base =
abstract f : int -> (int -> int)
default this.f (x : int) = fun y -> x + y
type Derived =
inherit Base
override this.f x =
let fn = base.f -x
fun y -> fn -y
您对curry参数的假设是正确的。下面的代码编译并运行良好:
type Base () =
abstract f : int * int -> int
default this.f (x : int,y : int) : int = x + y
type Derived () =
inherit Base()
override this.f (x : int,y : int) : int =
base.f(-x,-y)
注意:我使用了元组形参。这个原因可能是因为在curry参数中,它将函数分解为多个函数(每个函数接受1个参数)
@kvb在他的分析中是正确的,但如果你真的想覆盖一个curry方法,你可以。语法相当冗长:
type Base =
abstract f : int -> (int -> int)
default this.f (x : int) = fun (y : int) -> x + y
type Derived =
inherit Base
override this.f (x : int) =
let baseCall = base.f -x
fun (y : int) -> baseCall -y