5

差別化された共用体型宣言内でアクティブ パターンを使用することは可能ですか?

より正確には、次のおもちゃの例を考えてみましょう。

type T = 
    | A of int
    | B

let (|Negative|_|) t = 
    match t with
    | A n when n < 0 -> Some ()
    | _ -> None

let T_ToString = function
    | Negative () -> "negative!"
    | _ -> "foo!"

ここで、T で ToString() をオーバーライドしたいとします。T の型宣言内では、T_ToString がその時点でまだ宣言されていないため、T_ToString を参照できません。ToString() の前にアクティブなパターンと T_ToString を移動することはできません。これは、その時点では T がまだ宣言されていないためです。しかし、これもうまくいきません:

type T = 
    | A of int
    | B

    static member (|Negative|_|) t = 
        match t with
        | A n when n < 0 -> Some ()
        | _ -> None

    override this.ToString () = 
        match this with
        | Negative () -> "negative!"
        | _ -> "foo!"
4

3 に答える 3

4

Tあなたの質問は、陰性のテストは の本質的な操作であるため、その定義の一部であるべきであることを示唆しています。プロパティを定義することは、それを行う 1 つの方法です。

type T = 
  | A of int
  | B

  member this.IsNegative = 
    match this with
    | A n -> n < 0
    | _ -> false

  override this.ToString() = 
    if this.IsNegative then "negative!"
    else "foo!"

アクティブなパターンがまだ必要かどうかはわかりませんが、必要な場合は簡単です:

let (|Negative|_|) (x: T) = if x.IsNegative then Some() else None
于 2012-12-12T15:22:45.407 に答える
3

これは最も良い解決策ではありませんが、これを行うことができます:

type T = 
    | A of int
    | B

    static member internal ActivePattern t =
        match t with
        | A n when n < 0 -> Some ()
        | _ -> None

    override this.ToString () = 

        let (|Negative|_|) = T.ActivePattern

        match this with
        | Negative () -> "negative!"
        | _ -> "foo!"

let (|Negative|_|) = T.ActivePattern
于 2012-12-12T14:49:34.373 に答える
2

OK、解決策を見つけたと思います。最初に型を宣言し、次にアクティブなパターンをその外側で宣言し、最後に ToString() のオーバーライド実装で型を拡張します。

type T = 
    | A of int
    | B

let (|Negative|_|) t = 
    match t with
    | A n when n < 0 -> Some ()
    | _ -> None

type T with
    override this.ToString() = 
        match this with
        | Negative () -> "negative!"
        | _ -> "foo!"

ただし、警告が表示されるため、これはあまり良くありません

warning FS0060: Override implementations in augmentations are now deprecated. Override implementations should be given as part of the initial declaration of a type.
于 2012-12-12T14:43:07.160 に答える