gpt4 book ai didi

f# - 使用列表中的 Discriminated union 测试相等性

转载 作者:行者123 更新时间:2023-12-04 23:41:41 24 4
gpt4 key购买 nike

我定义了不同的类型:

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 的东西.

简而言之:如果列表、数组和可区分联合的元素支持相等,则它们支持相等。对于列表,它将是逐个元素的比较。

Basic Discriminated Unions 支持 Equality 开箱即用,但对象不支持,这就是为什么一旦您添加 TypeNull到列表比较失败。

试试这个:

type TypeNull() = class end
TypeNull() = TypeNull() // false

然后
let actual = TypeNull()
let expected = TypeNull()
actual = expected // false

所以,除非你为你的对象明确定义相等,否则默认行为是只有当两个实例相同时它才会产生真:
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

关于f# - 使用列表中的 Discriminated union 测试相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35728680/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com