まず第一に、インターフェイスの型パラメータが加算をサポートしていると述べる必要がある理由を完全には理解していないと思います-加算はの実装で使用されると思いますMyFunction
。その場合、インターフェイスの呼び出し元は知る必要はありませんそれについて。追加を公開したい場合は、別のメソッドとして追加するだけです。
type IMyInterface<'T> =
abstract Add : 'T * 'T -> 'T
abstract MyFunction : 'T -> 'T
inline
静的メンバーの制約は、関数や静的メンバー以外の場所ではうまく機能しないと思いますinline
(ただし、間違っている可能性があります)。ジェネリック型内で数値演算を使用する必要がある場合は、実装を(メソッド内で)キャプチャinline
してインターフェイスに格納するトリックを使用できます。F#の一般的な数学についての私のブログの最後にこの例があります。
秘訣は、必要な数値演算を使用してインターフェースを定義し、それを追加の引数としてコンストラクターに渡すことです。
type IAddition<'T> =
abstract Add : 'T * 'T -> 'T
type MyType<'T>(a:'T, b:'T, add:IAddition<'T>) =
member x.Sum = add.Add(a, b)
これまでのところ、これは標準の.NETの方法でインターフェイスを使用しています。インターフェイスは数値演算を表し、インターフェイスを介してそれらを呼び出します。ここでの秘訣は、2つの引数だけを取り、静的制約として必要とするinline
メソッドを追加することです。次に、メソッドはインターフェースを実装し、それを最後のパラメーターとしてに渡すことができます。Create
+
MyType
static member inline Create(a:^N, b:^N) =
let ops =
{ new IAddition< ^N > with
member x.Add(a, b) = a + b }
MyType< ^N >(a, b, ops)
これで、書き込みが可能にMyType<_>.Create(1, 2)
なり、整数の+
操作が自動的にキャプチャされてインターフェイスに格納されます(コードの残りの部分での作業が簡単になります)。