“基地”值只能用于直接调用被重写成员的基本实现

发布于 2024-11-04 11:47:41 字数 546 浏览 1 评论 0原文

为什么我不能在这里调用 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 接受单个参数然后编译。据推测,这与柯里化参数与元组参数有关,但上面的代码对我来说看起来不错。

Why can't I call the base implementation of f here:

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

The call to base.f elicits this compiler error:

error FS0419: 'base' values may only be used to make direct calls to the base implementations of overridden members

If I change f to take a single argument then it compiles. Presumably this is something to do with curried parameters vs tupled parameters, but the above code looks fine to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦过后 2024-11-11 11:47:41

我认为问题在于 base 无法通过闭包捕获 - 必须直接进行调用。然而,重写柯里化函数会自动创建一个闭包,因为只有第一个参数会立即应用。因此,即使看起来您确实使用 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

I believe that the issue is that base can't be captured by a closure - the call has to be made directly. However, overriding a curried function automatically creates a closure since only the first argument is applied immediately. Therefore, even though it looks like you are indeed using the base value to make a direct call to the base implementation of the overridden member, you're actually using the base value within a closure, which is illegal.

Unfortunately, I don't think there's any great way to work around this issue. Generally, you should avoid curried members when possible, but here's one alternative:

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
痴情 2024-11-11 11:47:41

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

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)

注意:我使用了元组参数。这个原因可能是因为在柯里化参数中,它将函数分解为多个函数(每个函数有 1 个参数)

Your assumption about the curried parameters is correct. The below code compiles and run fine:

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)

NOTE: I have used tupled parameters. This reason may be because in curried parameters it break downs the function in multiple functions (each function takes 1 parameter)

夏末染殇 2024-11-11 11:47:41

@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

@kvb is right in his analysis but if you really want to override a curried method you can. The syntax is pretty verbose though:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文