2017-03-17 10 views
3
特に

、私はこのタイプの拡張メソッドを書きたい:そのコード付きジェネリック型の拡張メソッドを書くには、1つの型変数は文字列でなければならないのですか?

type Frame<'TRowKey, string when 'TRowKey : equality> with 
    member frame.someMethod = 
    // code 

、私はこのエラーを取得しています:Stringstringを交換

Unexpected identifier in type name. Expected infix operator, quote symbol or other token.

は、同じ結果を与えます。

元タイプはDeedleライブラリのFrame<'TRowKey, 'TColumnKey (requires equality and equality)>です。

+0

タイプ制約は左側に書かれていなければならないことに注意してください。 – Gustavo

答えて

2

私はこのコードをテストするDeedleを持っていないが、あなたは、.NET拡張メソッドを使用する必要があります。

open System 

[<Runtime.CompilerServices.Extension>] 
module Extensions = 
    [<Runtime.CompilerServices.Extension>] 
    let someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body 

これは、呼び出しをscrwtp同様「慣用的な方法」(私は好きではないですidomaticityについて議論する)、同時に拡張メソッドとしてC#から機能します。

あなたはF#などだけでなく、拡張子から、それを使用したい場合は、それが型として宣言する必要があります。それにその場合

[<Runtime.CompilerServices.Extension>] 
type Extensions = 
    [<Runtime.CompilerServices.Extension>] 
    static member someMethod<'TRowKey when 'TRowKey : equality> (frame :Frame<'TRowKey, string>) = // body 

だから今、あなたはとインテリセンスを入力することができますが拡張子のみを示しています2番目のパラメータは文字列です。

+1

これはおそらく、モジュールletバインディングではなく、プレースホルダー型の静的メンバーである必要があります。 – scrwtp

+1

@scrwtp F#の拡張子としても使用したい場合はyesです。私はちょうど他のバージョンを追加しました。 – Gustavo

+0

ありがとう!私も近くにいませんでした –

5

@Gustavoは、拡張メソッドを使用する方法を徹底的に回答しました。

type Frame<'row, 'col> = { row: 'row; col: 'col } 

module Frame = 
    let restricted (frame: Frame<'row, string>) = frame 

Frame.restricted { row = 3; col = "test" } // compiles 
Frame.restricted { row = 3; col = 5 }  // doesn't 

書くとき、私はクリーンなアプローチを検討したいものです:あなたは、これは(C#の相互運用機能のような)拡張メソッドであるために特に強い理由がない場合でも、あなただけの単純な関数で行くかもしれませんF#専用コード - 型の本質的な部分として意味がなく、属性からのノイズが少ない場合にメソッドに適したlet-bound関数。

関連する問題