【问题标题】:F# compilation error: Unexpected type applicationF# 编译错误:意外类型的应用程序
【发布时间】:2011-02-14 03:26:08
【问题描述】:

在 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 的调用中删除 不会导致错误。
  • 是的,但这有效地使它在内部使用 System.Object。如果您将 typeof 用作某些测试的一部分,那将有点没用。

标签: generics f# pipelining


【解决方案1】:

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

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

  • &lt;types&gt; expr,然后使用&lt;types&gt; 作为类型参数,expr 作为表达式 论据。
  • expr,然后使用 expr 作为表达式参数。
  • 否则不使用表达式参数或类型参数。
  • 如果 [method] 标有 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多