3

为什么我不能调用这里的base实现f

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为采用单个参数,那么它会编译。大概这与咖喱参数与元组参数有关,但上面的代码对我来说看起来不错。

4

3 回答 3

5

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

不幸的是,我认为没有什么好的方法可以解决这个问题。一般来说,你应该尽可能避免使用咖喱成员,但这里有一种选择:

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
于 2011-05-01T18:15:29.377 回答
0

您对咖喱参数的假设是正确的。下面的代码编译并运行良好:

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)

注意:我使用了元组参数。这个原因可能是因为在 curried 参数中它分解了多个函数中的函数(每个函数需要 1 个参数)

于 2011-05-01T10:22:08.437 回答
0

@kvb 在他的分析中是正确的,但如果你真的想覆盖一个咖喱方法,你可以。语法虽然很冗长:

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
于 2018-01-15T12:11:12.397 回答