F#编译错误:意外的类型应用程序

时间:2010-04-30 07:53:23

标签: generics f# pipelining

在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 个答案:

答案 0 :(得分:14)

不支持在将方法视为第一类值时提供类型参数。我检查了F# specification,这里有一些重要的内容:

  

14.2.2项目合格查找
  [如果应用程序表达式以:]

开头      
      
  • <types> expr ,然后使用<types>作为类型参数,使用expr作为表达式   参数。
  •   
  • expr ,然后使用expr作为表达式参数。
  •   
  • 否则不使用表达式参数或类型参数。
  •   
  • 如果[方法]标有   RequiresExplicitTypeArguments属性然后显式类型参数必须具有   已被给予。
  •   

如果指定类型参数和参数,则第一种情况适用,但正如您所看到的,规范也需要一些实际参数。不过,我不太清楚这背后的动机是什么。

无论如何,如果你在成员的类型签名中的任何地方使用type参数,那么你可以使用类似这样的类型注释来指定它:

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>