1

私が次の識別された結合と価値を持っているとしましょう:

type DisUnion = 
    | One of string
    | Two of string
    | Three of string * string

let myVal = One("One")

myVal次のように、パターンマッチングを使用して、どのケースが属するかを判断できることを知っています。

let whatever (x : DisUnion) = match x with
    | One(str) -> "It was One"
    | Two(str) - > "It was two"
    | Three(str, str) -> "It was three"

しかし、次のように、パターンマッチングなしでケース識別子を判別できる演算子またはメソッドを見つけることができないようです。

let isOne (x : DisUnion) = x :? One //I thought this would work, but it doesn't.

どうすればいいですか?どんな助けでも大歓迎です。

4

2 に答える 2

6
let isOne = function One(_) -> true | _ -> false

これは次と同等であることに注意してください。

let isOne x = match x with One(_) -> true | _ -> false
于 2012-06-02T11:52:48.990 に答える
2

F#にはそのような演算子は組み込まれていませんが、目標を達成するためのいくつかの異なるアプローチがあります。

タイプチェックを失い、通常は使用されない新しいアプローチは、リフレクションによるものです。DisUnion判別ユニオンは、F#コンパイラによって、基本クラスおよび各ユニオンケースOne、、、TowおよびThreeのサブクラスとして使用して実装されていることに注意してくださいDisUnion。したがって、次の演算子を実装できます。

let (=?) duInstance caseName = 
    let duInstanceTy = duInstance.GetType()
    duInstanceTy.Name = caseName

そしてそれをそのように使用します:

> One("hi") =? "One";;
val it : bool = true
> One("hi") =? "Two";;
val it : bool = false
> One("hi") =? "NotValid";;
val it : bool = false

ただし、より一般的なのは、静的メンバーのセットを実装しDisUnionて、静的に型チェックされた方法でジョブを実行することです。実装するのは少し冗長ですが、静的メンバーを使用するのは良いので、1回限りのコストです。

type DisUnion = 
    | One of string
    | Two of string
    | Three of string * string
    static member isOne x =
        match x with
        | One _ -> true
        | _ -> false
    static member isTwo x =
        match x with
        | Two _ -> true
        | _ -> false
    static member isThree x =
        match x with
        | Three _ -> true
        | _ -> false

そしてそれをそのように使用します:

> DisUnion.isOne (One("hi"));;
val it : bool = true
> DisUnion.isOne (Two("hi"));;
val it : bool = false
> DisUnion.isOne (NotValid("hi"));;

  DisUnion.isOne (NotValid("hi"));;
  ----------------^^^^^^^^

C:\stdin(5,17): error FS0039: The value or constructor 'NotValid' is not defined
于 2012-06-02T14:07:24.007 に答える