通过案例标识符与识别联合“F#标识符、案例

2023-09-04 13:04:54 作者:陌上花開°紅顏醉

有没有办法在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个无数据的情况下失败。

854 AUTOSAR TPS GenericStructureTemplate10 通用模板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)

 
精彩推荐
图片推荐