你可以使用F#反射API来实现这个。
Reflection.FSharpType.GetUnionCases
可以返回DU案例的完整列表,每个案例表示为
UnionCaseInfo
结构,具有以下有用特性
Name
和
Tag
:
> Reflection.FSharpType.GetUnionCases(typeof<T>) |> Array.map (fun c -> c.Tag)
[|0; 1|]
cmp_t
功能),签出
the
Reflection.FSharpValue.GetUnionFields
function
联合案例信息
> let x = A 42
> let caseInfo, fields = Reflection.FSharpValue.GetUnionFields(x, typeof<T>)
> caseInfo.Tag
0
但是,请记住,对于F#判别并集,编译器将自动生成结构比较,因此
cmpt_t
功能冗余:
> A 42 < A 54
true
> A 3 > B 1.0
false
// Or more generally:
> (A 42 :> System.IComparable<T>).CompareTo(A 54)
-1
let cmp_t (x: 'a when 'a :> System.IComparable<'a>) y =
(x :> System.IComparable<'a>).CompareTo(y)
> cmp_t (A 42) (A 54)
-1
看哪!标准库中已经有这样的函数。它叫
compare
:
> compare (A 42) (A 54)
-1