在F#中,案例标识符的'是X'运算符?

时间:2012-06-02 11:40:34

标签: .net f# functional-programming

假设我有以下歧视的联合和价值:

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.

我该怎么做?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:6)

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

请注意,这相当于:

let isOne x = match x with One(_) -> true | _ -> false

答案 1 :(得分:2)

F#中没有这样的运算符,但实现目标有几种不同的方法。

一种新的方法,即失去类型检查,因此通常不会被使用,是通过反射。我们注意到,判别联合是由F#编译器实现的,在您的示例中,使用DisUnion作为基类和每个联合案例OneTow和{{1} }作为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

并像这样使用它:

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