Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
579 views
in Technique[技术] by (71.8m points)

generics - F# compilation error: Unexpected type application

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"
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...