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

9
在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"

不确定,但从调用Bar中删除<Int32>会导致没有错误。 - OJ.
是的,但实际上它会在内部使用 System.Object。如果您要在某些测试中使用 typeof<'t>,那么它可能有点无用。 - Jim Burger
1个回答

14
看起来在将方法视为一等值时提供类型参数是不受支持的。我查看了F#规范,以下是一些重要内容:
14.2.2 项目限定查找 [如果应用程序表达式以以下方式开始:]
  • <types> expr,则使用<types>作为类型参数,expr作为表达式参数。
  • expr,则使用expr作为表达式参数。
  • 否则不使用表达式参数或类型参数。
  • 如果[method]带有RequiresExplicitTypeArguments属性,则必须给出显式类型参数。
如果您指定了类型参数和参数,则适用第一种情况,但正如您所看到的,规范还需要一些实际参数。虽然我不太确定这背后的动机是什么。
无论如何,如果您在成员的类型签名中的任何位置使用类型参数,则可以使用类型注释指定它,如下所示:
type Foo() = 
  member this.BarT> (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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接