F#编译错误:意外的类型应用程序 [英] F# compilation error: Unexpected type application

查看:180
本文介绍了F#编译错误:意外的类型应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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 GT; //编译器返回错误:Unexpected type application


解决方案

不支持将方法作为第一类值提供时提供类型参数。我检查了 F#规范,并在这里是一些重要的部分:


14.2.2项目限定查找

[If应用程序表达式开始于:]




  • <类型> expr ,然后使用<类型> 作为类型参数,并使用 expr 作为表达式
    参数。
  • expr ,然后使用expr作为表达式参数。

  • 否则使用无表达式参数或类型参数。

  • 如果[method]标记为
    RequiresExplicitTypeArguments 属性,则显式类型参数必须有
    给定。

如果指定了类型参数和参数,则第一种情况适用,可以看,具体还需要一些实际的论点。不过,我不确定这背后的动机是什么。



无论如何,如果您在成员的类型签名中的任何位置使用type参数,那么您可以使用类型注释来指定它:

  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>


In F#, given the following class:

type Foo() =
    member this.Bar<'t> (arg0:string) = ignore()

Why does the following compile:

let f = new Foo()
f.Bar<Int32> "string"

While the following won't compile:

let f = new Foo()
"string" |> f.Bar<Int32> //The compiler returns the error: "Unexpected type application"

解决方案

It looks that providing type parameters when treating method as a first class value isn't supported. I checked the F# specification and here are some important bits:

14.2.2 Item-Qualified Lookup
[If the application expression begins with:]

  • <types> expr, then use <types> as the type arguments and expr as the expression argument.
  • expr, then use expr as the expression argument.
  • otherwise use no expression argument or type arguments.
  • If the [method] is labelled with the RequiresExplicitTypeArguments attribute then explicit type arguments must have been given.

If you specify type arguments and arguments, then the first case applies, but as you can see, the specification requires some actual arguments too. I'm not quite sure what is the motivation behind this, though.

Anyway, if you use the type parameter anywhere in the type signature of the member, then you can specify it using type annotations like this:

type Foo() = 
  member this.Bar<´T> (arg0:string) : ´T = 
    Unchecked.defaultof<´T>

let f = new Foo()
"string" |> (f.Bar : _ -> Int32)

On the other hand, if you don't use the type parameter anywhere in the signature, then I'm not quite sure why you need it in the first place. If you need it just for some runtime processing, then you may be able to take the runtime type representation as an argument:

type Foo() = 
  member this.Bar (t:Type) (arg0:string) = ()

let f = new Foo() 
"string" |> f.Bar typeof<Int32>

这篇关于F#编译错误:意外的类型应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆