3

F# タプルの型拡張メソッドを作成しようとしています。このコードは問題なくコンパイルされます。

type System.Tuple<'a, 'b> with
    member this.ToParameter name =
        match this with
        | this -> sprintf "%s=%O,%O" name (this.Item1, this.Item2)

ただし、このメソッドを呼び出そうとすると:

printfn "%s" (("cat", 2).ToParameter("test"))

「このフィールド、コンストラクター、またはメンバー 'ToParameter' は定義されていません」というエラーが表示されます。インタープリターでは、次の式は、それらの型を何らかの形式の System.Tuple'2 として報告します。

typedefof<'a * 'b>.FullName
(1, 2).GetType().FullName

Visual Studio で式にカーソルを合わせると、次のようになります。

let a = 1, 2

int * int の型を報告します。この型を拡張しようとすると、またはそれが一般的な等価物である 'a * 'b である場合、エラーが発生します。

F# タプルの一般的な拡張を作成することは可能ですか?

4

2 に答える 2

4

あなたの質問への答えは、私がここで同様の質問に与えた答えとほとんど同じになります。つまり、型拡張が機能しない理由は、「System.Tuple<_,...,_>タプルのエンコードされた形式のみであり、コンパイラーによって使用される静的表現ではないためです。仕様の6.3.2タプル式を参照してください。」

タイプ拡張を使用するには、最初にボックス化してから、タプル値をキャストする必要があります。

let tuple = box ("cat", 2) :?> System.Tuple<string,int>
printfn "%s" (tuple.ToParameter("test"))

余談ですが、型拡張でわずかな構文エラーが発生したことにも注意してください。次のようになります。

type System.Tuple<'a, 'b> with
    member this.ToParameter name =
        match this with
        | this -> sprintf "%s=%O,%O" name this.Item1 this.Item2 //removed parens around Item1 and Item2
于 2013-02-25T03:54:28.777 に答える