有没有办法在F#中比较受歧视工会通过他们的情况,标识符?
键入MyUnion =
|字符串MyString中
|整型敏
令x = MyString的(你好)
设y = MyString的(再见)
令z =敏(25)
让compareCases A B =
// compareCases X Y =真
// compareCases X Z = FALSE
// compareCasesÿZ =假
在一个通用的方法的我如何实施 compareCases
功能?
即。类似于以下,但更通用的(反射是确定):
让compareCases A,B =
匹配带
| MyString的(_) - >匹配B与| MyString的(_) - >真| _ - >假
|敏(_) - >匹配B与|敏(_) - >真| _ - >假
解决方案
使用的GetType(问题)是,如果你有2个无数据的情况下失败。
下面是做这件事:(编辑因为previous UnionTagReader没有被缓存)
键入MyDU =
|情况1
|案例2
|为int的情形3
|整型CASE4
键入TagReader<T>()=
让TR =
断言FSharpType.IsUnion(typeof运算<T>)
FSharpValue preComputeUnionTagReader。(typeof运算<'T>中System.Reflection.BindingFlags.Public)
会员this.compareCase(X:'T)(Y:'T)=
(TR X)=(TR Y)
让TR = TagReader< MyDU>()
让C1 =案例1
让C2 =第2种情况
让C3 =情形3(0)
让C3'=情形3(1)
让C4 = CASE4(0)
断言(c1.GetType()= c2.GetType())//这就是为什么你不能使用的GetType()
断言tr.compareCase C1 C1
断言没有(tr.compareCase C1 C2)
断言tr.compareCase C3 C3'
断言没有(tr.compareCase C3 C4)
Is there a way to compare discriminated unions by their case-identifiers in F#?
type MyUnion =
| MyString of string
| MyInt of int
let x = MyString("hello")
let y = MyString("bye")
let z = MyInt(25)
let compareCases a b =
// compareCases x y = true
// compareCases x z = false
// compareCases y z = false
How do I implement compareCases
function in a generic way?
I.e. something like the following, but more generic (reflection is ok):
let compareCases a b =
match a with
| MyString(_) -> match b with | MyString(_) -> true | _ -> false
| MyInt(_) -> match b with | MyInt(_) -> true | _ -> false
解决方案
The problem with using GetType() is that it fails if you have 2 'dataless' cases.
Here is one way to do it: (Edited because the previous UnionTagReader was not being cached)
type MyDU =
| Case1
| Case2
| Case3 of int
| Case4 of int
type TagReader<'T>() =
let tr =
assert FSharpType.IsUnion(typeof<'T>)
FSharpValue.PreComputeUnionTagReader(typeof<'T>, System.Reflection.BindingFlags.Public)
member this.compareCase (x:'T) (y:'T) =
(tr x) = (tr y)
let tr = TagReader<MyDU>()
let c1 = Case1
let c2 = Case2
let c3 = Case3(0)
let c3' = Case3(1)
let c4 = Case4(0)
assert (c1.GetType() = c2.GetType() ) //this is why you can not use GetType()
assert tr.compareCase c1 c1
assert not (tr.compareCase c1 c2)
assert tr.compareCase c3 c3'
assert not (tr.compareCase c3 c4)