Let's say I have the following discriminated union and value:
type DisUnion =
| One of string
| Two of string
| Three of string * string
let myVal = One("One")
I know I can use pattern matching to determine which case myVal
belongs to, like this:
let whatever (x : DisUnion) = match x with
| One(str) -> "It was One"
| Two(str) - > "It was two"
| Three(str, str) -> "It was three"
But I can't seem to find an operator or method that allows me to determine the case identifier without pattern matching, like:
let isOne (x : DisUnion) = x :? One //I thought this would work, but it doesn't.
How would I do this? Any help is appreciated.
let isOne = function One(_) -> true | _ -> false
请注意,这等效于:
let isOne x = match x with One(_) -> true | _ -> false
There's no such operator built into F#, but there are a couple different approaches to achieving your goal.
A novel approach, which loses type checking and thus wouldn't typically be used, is via reflection. We note that discriminant unions are implement by the F# compiler using, in your example, DisUnion
as a base class and each of the union cases, One
, Tow
, and Three
as subclasses of DisUnion
. Thus we can implement the following operator:
let (=?) duInstance caseName =
let duInstanceTy = duInstance.GetType()
duInstanceTy.Name = caseName
and use it like so:
> One("hi") =? "One";;
val it : bool = true
> One("hi") =? "Two";;
val it : bool = false
> One("hi") =? "NotValid";;
val it : bool = false
More typical, however, would be to implement a set of static members on DisUnion
to do the job in a statically type-checked way. It's a bit verbose to implement, but it's a one time cost since using the static members is nice.
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
and use it like so:
> 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.