4

F# 4.0、.NET 4.6 を使用した次のコード スニペットを検討してください。

type X<'T> = Y of 'T

type XS = X<string>
type XI = X<int>

type X<'T when 'T :> string> with
    static member X = 2
    static member take (s: 'T) = s

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module XS =
    let foo = 10
    let create s = XS.Y s
    let test = XI.take 2    // expected only string allowed, XI.take should not exist

型の拡張type X<'T when 'T :> string> withが尊重されるか (この場合は、stringが封印されているか、 be に制限さ'Tれているため、エラーを意味しますstring)、または構文エラーが発生することを期待します。

さらに、次の構文も使用できますが、これは通常の型定義 ( なしwith)では構文エラーになります。

type X<'T> when 'T :> string with
    static member X = 2
    static member take (s: 'T) = s

私の推測では、拡張機能では制約が単純に無視されます。それは設計によるものですか?または、機能するはずですか?もしそうなら、どのように?

型拡張を少し試して、特定の具体的な型にのみ適用される特定のメソッドのセットを作成できるかどうか、またはさらに制限された具体的な型 (継承によっても実行できるもの) を作成できるかどうか疑問に思ったときに、これらすべてにたどり着きました。 )。

4

1 に答える 1

3

コンパイラはあなたのコードを拒否すべきだと思いますが、いくつかの観察事項があります:

  1. 「外部」拡張機能を使用する場合 (たとえば、定義と拡張機能を別のモジュールに配置する場合 - Type Extensionsを参照) は動作が異なることに注意してください。この場合、コンパイラは拡張機能にエラーのフラグを立てます。
  2. 型パラメーターの特定の具体的な値に対してのみ表示されるインスタンス拡張メソッドが必要な場合は、C# スタイルの拡張メソッドを使用できます (これは上記のリンクでも説明されています) 。ただし、C# は静的拡張メンバーをサポートしていないため、このトリックをシナリオに適用する方法はありません。
于 2016-10-13T14:32:29.390 に答える