代码之家  ›  专栏  ›  技术社区  ›  Jim Burger

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

  •  9
  • Jim Burger  · 技术社区  · 14 年前

    在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 回复  |  直到 14 年前
        1
  •  14
  •   Tomas Petricek    14 年前

    似乎不支持在将方法视为第一类值时提供类型参数。我查过了 F# specification 以下是一些重要的信息:

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

    • <types> ,然后使用 <类型> 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>