在列表中测试与 Dicriminated union 的相等性
testing equality with Dicriminated union in a list
我定义了不同的类型:
type TypeNull() = class end
type MyType1 = {
a:int;
b:int
}
type MyType2 = {
a:string;
b:int
}
type MyType3 = {
a:string;
b:DateTime
}
和使用它们的不同歧视联盟:
type myDU =
| A of int
| B of string
| C of string
type myDU2 =
| D of MyType1
| E of MyType2
| F of TypeNull
我有将 myDU 映射到 myDU2 的函数:
let applyArray = function
| A x -> [E({a="1"; b=2})]
| B x -> [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
| C x -> [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
然后两个测试来测试相等性:
let arrayValueEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
let actual = applyArray <| B("xxx")
actual = expected
let arrayValueNullEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let actual = applyArray <| C("xxx")
actual = expected
在 fsi 中给出:
val applyArray : _arg1:myDU -> myDU2 list
val arrayValueEquals : bool = true
val arrayValueNullEquals : bool = false
我的问题如下,为什么第一个测试成功,第二个不成功?
这里是完整的要点:
// Learn more about F# at http://fsharp.net. See the 'F# Tutorial' project
// for more guidance on F# programming.
#load "Library1.fs"
open test2
open System
type TypeNull() = class end
type MyType1 = {
a:int;
b:int
}
type MyType2 = {
a:string;
b:int
}
type MyType3 = {
a:string;
b:DateTime
}
type myDU =
| A of int
| B of string
| C of string
type myDU2 =
| D of MyType1
| E of MyType2
| F of TypeNull
let applyArray = function
| A x -> [E({a="1"; b=2})]
| B x -> [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
| C x -> [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let arrayValueEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
let actual = applyArray <| B("xxx")
actual = expected
let arrayValueNullEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let actual = applyArray <| C("xxx")
actual = expected
在 F# 中有一个叫做 Structural Equality 的东西。
简而言之:如果列表、数组和可辨别联合的元素支持相等,则它们也支持相等。对于列表,它将逐个元素进行比较。
基本区分联合支持开箱即用的平等,但对象不支持,这就是为什么一旦您将 TypeNull
添加到列表中,比较就会失败。
试试这个:
type TypeNull() = class end
TypeNull() = TypeNull() // false
然后
let actual = TypeNull()
let expected = TypeNull()
actual = expected // false
因此,除非您明确定义对象的相等性,否则默认行为是只有当两个实例相同时它才会产生 true:
type TypeNull() = class end
let a = TypeNull()
let actual = a
let expected = a
actual = expected // true
但对于 DU,它会自动工作:
type TypeNull = TypeNull
TypeNull = TypeNull // true
然后
let actual = TypeNull
let expected = TypeNull
actual = expected // True
我定义了不同的类型:
type TypeNull() = class end
type MyType1 = {
a:int;
b:int
}
type MyType2 = {
a:string;
b:int
}
type MyType3 = {
a:string;
b:DateTime
}
和使用它们的不同歧视联盟:
type myDU =
| A of int
| B of string
| C of string
type myDU2 =
| D of MyType1
| E of MyType2
| F of TypeNull
我有将 myDU 映射到 myDU2 的函数:
let applyArray = function
| A x -> [E({a="1"; b=2})]
| B x -> [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
| C x -> [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
然后两个测试来测试相等性:
let arrayValueEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
let actual = applyArray <| B("xxx")
actual = expected
let arrayValueNullEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let actual = applyArray <| C("xxx")
actual = expected
在 fsi 中给出:
val applyArray : _arg1:myDU -> myDU2 list
val arrayValueEquals : bool = true
val arrayValueNullEquals : bool = false
我的问题如下,为什么第一个测试成功,第二个不成功?
这里是完整的要点:
// Learn more about F# at http://fsharp.net. See the 'F# Tutorial' project
// for more guidance on F# programming.
#load "Library1.fs"
open test2
open System
type TypeNull() = class end
type MyType1 = {
a:int;
b:int
}
type MyType2 = {
a:string;
b:int
}
type MyType3 = {
a:string;
b:DateTime
}
type myDU =
| A of int
| B of string
| C of string
type myDU2 =
| D of MyType1
| E of MyType2
| F of TypeNull
let applyArray = function
| A x -> [E({a="1"; b=2})]
| B x -> [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
| C x -> [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let arrayValueEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});E({a="5"; b=24})]
let actual = applyArray <| B("xxx")
actual = expected
let arrayValueNullEquals =
let expected = [D({a=1; b=2});E({a="1"; b=2});F(TypeNull())]
let actual = applyArray <| C("xxx")
actual = expected
在 F# 中有一个叫做 Structural Equality 的东西。
简而言之:如果列表、数组和可辨别联合的元素支持相等,则它们也支持相等。对于列表,它将逐个元素进行比较。
基本区分联合支持开箱即用的平等,但对象不支持,这就是为什么一旦您将 TypeNull
添加到列表中,比较就会失败。
试试这个:
type TypeNull() = class end
TypeNull() = TypeNull() // false
然后
let actual = TypeNull()
let expected = TypeNull()
actual = expected // false
因此,除非您明确定义对象的相等性,否则默认行为是只有当两个实例相同时它才会产生 true:
type TypeNull() = class end
let a = TypeNull()
let actual = a
let expected = a
actual = expected // true
但对于 DU,它会自动工作:
type TypeNull = TypeNull
TypeNull = TypeNull // true
然后
let actual = TypeNull
let expected = TypeNull
actual = expected // True