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

StackOverflow https://stackoverflow.com/questions/2743051

  •  02-10-2019
  •  | 
  •  

Вопрос

В 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"
Это было полезно?

Решение

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

14.2.2 Квалифицированного товара
Если выражение приложения начинается с:

  • <types> экспл, Затем используйте <types> как аргументы типа и 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>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top