'base'值只能用于直接调用重写成员的基本实现

jon*_*son 3 inheritance f# overriding derived base

为什么我不能basef这里调用实现:

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
Run Code Online (Sandbox Code Playgroud)

调用base.f引发此编译器错误:

error FS0419: 'base' values may only be used to make direct calls to the base implementations of overridden members
Run Code Online (Sandbox Code Playgroud)

如果我f改为采用单个参数,那么它就会编译.据推测,这与curried参数与tupled参数有关,但上面的代码对我来说很好.

kvb*_*kvb 5

我认为问题是base关闭不能捕获 - 必须直接调用.但是,覆盖curried函数会自动创建闭包,因为只会立即应用第一个参数.因此,即使您确实使用该base值来直接调用重写成员的基本实现,您实际上是base在闭包中使用该值,这是非法的.

不幸的是,我认为没有什么好方法可以解决这个问题.一般来说,你应尽可能避免使用curried成员,但这里有一个替代方案:

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
Run Code Online (Sandbox Code Playgroud)

  • @jon - 可以说这是一个编译错误,有这样一个误导性的错误信息.此外,没有任何基本限制可以阻止基本成员从闭包内调用,尽管这不是一个需要解决的小问题.但是,我认为你的代码__not__本质上是惯用的.在模块中使用curried let-bound函数是惯用的,但使用curried成员并不是惯用的,完全是因为这样的问题. (2认同)