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"
4

1 に答える 1

14

メソッドをファーストクラスの値として扱う場合の型パラメータの提供はサポートされていないようです。F# の仕様を確認したところ、重要な点がいくつかあります。

14.2.2 Item-Qualified Lookup
[アプリケーション式が次で始まる場合]

  • <types>expr、次に<types>型引数および式引数として使用しexprます。
  • exprの場合、式の引数として expr を使用します。
  • それ以外の場合は、式引数または型引数を使用しません。
  • [メソッド] が 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>
于 2010-04-30T09:17:19.803 に答える