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

孤街醉人 提交于 2019-12-10 20:43:11

问题


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.


回答1:


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



回答2:


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)




回答3:


@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


来源:https://stackoverflow.com/questions/5847202/base-values-may-only-be-used-to-make-direct-calls-to-the-base-implementations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!