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



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

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

最新更新