Ошибка компиляции F#: Неожиданное приложение типа

В F#, учитывая следующий класс:

type Foo() =
    member this.Bar<'t> (arg0:string) = ignore()

Почему делает следующую компиляцию:

let f = new Foo()
f.Bar<Int32> "string"

В то время как следующее не скомпилирует:

let f = new Foo()
"string" |> f.Bar<Int32> //The compiler returns the error: "Unexpected type application"
9
задан Jim Burger 30 April 2010 в 07:53
поделиться

1 ответ

Похоже, что предоставление параметров типа при обработке метода как значения первого класса не поддерживается. Я проверил спецификацию F # и вот несколько важных моментов:

14.2.2 Поиск с определением элемента
[Если выражение приложения начинается с:]

  • expr , затем используйте в качестве аргументов типа и expr в качестве аргумента выражения .
  • expr , затем используйте expr в качестве аргумента выражения.
  • в противном случае не используйте аргумент выражения или аргументы типа.
  • Если [метод] помечен атрибутом RequiresExplicitTypeArguments , тогда должны быть указаны аргументы явного типа .

Если вы указываете аргументы типа и аргументы, тогда применяется первый случай, но, как вы можете видеть, спецификация также требует некоторых фактических аргументов. Однако я не совсем уверен, что за этим стоит.

В любом случае, если вы используете параметр типа где-нибудь в сигнатуре типа члена, то вы можете указать его, используя аннотации типа, например:

type Foo() = 
  member this.Bar<´T> (arg0:string) : ´T = 
    Unchecked.defaultof<´T>

let f = new Foo()
"string" |> (f.Bar : _ -> Int32)

С другой стороны, если вы не используете параметр типа где-нибудь в подпись, то я не совсем понимаю, зачем она вам вообще нужна. Если вам это нужно только для некоторой обработки во время выполнения, вы можете принять представление типа среды выполнения в качестве аргумента:

type Foo() = 
  member this.Bar (t:Type) (arg0:string) = ()

let f = new Foo() 
"string" |> f.Bar typeof<Int32>
14
ответ дан 4 December 2019 в 14:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: