2016-03-01 3 views
4

Я определил различные типы:тестирование равенства с Dicriminated союза в списке

type TypeNull() = class end 

type MyType1 = { 
    a:int; 
    b:int 
} 

type MyType2 = { 
    a:string; 
    b:int 
} 

type MyType3 = { 
    a:string; 
    b:DateTime 
} 

и различные disciminated союза, которые их используют:

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 
+0

Вы распечатайте значения 'actual', чтобы увидеть, что это было? Я подозреваю, что TypeNull() не так, как вы думаете. Или вы попробовали отправить ожидаемое и актуальное значение F # Interactive для просмотра типов. –

+0

это дает мне: > TypeNull() ;; val it: TypeNull = FSI_0002 + TypeNull – Arthis

+0

> let actual = applyArray <| С ("ххх") ;; val actual: myDU2 list = [D {a = 1; b = 2;}; E {a = "1"; b = 2;}; F FSI_0002 + TypeNull] – Arthis

ответ

7

В F # есть нечто, называемое Structural Equality.

Вкратце: списки, массивы и Дискриминационные союзы поддерживают равенство, если их элементы поддерживают равенство. Для списков это будет элемент путем сравнения элементов.

Базовые Дискриминационные Союзы поддерживают Равенство вне коробки, но объекты не делают, и поэтому, как только вы добавляете TypeNull к списку сравнения, не удается.

Try просто:

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 

но с ПН работает автоматически:

type TypeNull = TypeNull 
TypeNull = TypeNull // true 

затем

let actual = TypeNull 
let expected = TypeNull 
actual = expected // True 
+0

Я использовал тип a() = конец класса для типа «emulate» a = {}. Так это не одно и то же? – Arthis

+0

Да, но в F # это не Дискриминационный союз. Это простой объект. Объекты по умолчанию равны, если экземпляры одинаковы. Это то же самое в C#. – Gustavo

+0

Я буду жевать то, что ты сказал мне сегодня вечером ... Я должен подумать об этом. Я чего-то не получу, но это конец дня, вот так .. – Arthis

Смежные вопросы