«базовые» значения могут использоваться только для прямых вызовов базовых реализаций переопределенных членов - PullRequest
3 голосов
/ 01 мая 2011

Почему я не могу назвать 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 на один аргумент, он будет скомпилирован. Предположительно, это как-то связано с параметрами curry и параметрами tupled, но приведенный выше код выглядит хорошо для меня.

Ответы [ 3 ]

5 голосов
/ 01 мая 2011

Я считаю, что проблема в том, что 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
0 голосов
/ 15 января 2018

@ 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
0 голосов
/ 01 мая 2011

Ваше предположение о параметрах карри верное.Приведенный ниже код компилируется и работает нормально:

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 параметр)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...