Ошибка компиляции 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"

1 ответ

Решение

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

14.2.2. Квалифицированный на предмет поиск
[Если выражение приложения начинается с:]

  • <types>expr, затем используйте <types> в качестве аргументов типа и 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 где-либо в сигнатуре, я не совсем уверен, зачем он вам нужен. Если вам это нужно только для некоторой обработки во время выполнения, вы можете принять представление типа времени выполнения в качестве аргумента:

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

let f = new Foo() 
"string" |> f.Bar typeof<Int32>
Другие вопросы по тегам