[英]Using `should equal` with sequences in F# and FsUnit
I am using FsUnit.Xunit
.我正在使用FsUnit.Xunit
。 I am getting a failure for the following test case:以下测试用例失败:
[<Fact>]
let ``Initialization of DFF`` () =
dff Seq.empty Seq.empty |> should equal (seq {Zero})
The test failure is:测试失败是:
Message:
FsUnit.Xunit+MatchException : Exception of type 'FsUnit.Xunit+MatchException' was thrown.
Expected: Equals seq [Zero]
Actual: seq [Zero]
Stack Trace:
That.Static[a](a actual, IMatcher`1 matcher)
Signal.Initialization of DFF() line 11
I get the same error if the test is:如果测试是,我会得到同样的错误:
[<Fact>]
let ``Initialization of DFF`` () =
dff Seq.empty Seq.empty |> should equal (Seq.singleton Zero)
I have never tested equality of sequences using FsUnit.Xunit
, so I am confused what's going on.我从未使用FsUnit.Xunit
测试过序列的相等性,所以我很困惑发生了什么。 I'm not even for sure what the failure message is telling me, as it seems to be saying that the expected and actual are the same.我什至不确定失败消息告诉我什么,因为它似乎在说预期和实际是相同的。 I can get this to work fine by converting the sequences to lists, but it would be nice to not have to do that.我可以通过将序列转换为列表来使其正常工作,但不必这样做会很好。
Could someone explain what's going on here?有人可以解释这里发生了什么吗? It seems I'm not understanding the error message and thus probably something about Equals
and comparing sequence values (literals?).似乎我不理解错误消息,因此可能是关于Equals
和比较序列值(文字?)。 Thanks.谢谢。
Source code to be able to reproduce (I think this is everything):能够重现的源代码(我认为这就是一切):
type Bit =
| Zero
| One
type Signal = seq<Bit>
let Nand a b =
match a, b with
| Zero, Zero -> One
| Zero, One -> One
| One, Zero -> One
| One, One -> Zero
let Not input =
Nand input input
let And a b =
Not (Nand a b)
let Or a b =
Nand (Not a) (Not b)
let private liftToSignal1 op (signal: Signal) : Signal =
Seq.map op signal
let private liftToSignal2 op (signalA: Signal) (signalB: Signal) : Signal =
Seq.map2 op signalA signalB
let Not' = liftToSignal1 Not
let And' = liftToSignal2 And
let Or' = liftToSignal2 Or
let rec dff data clock : Signal =
seq {
yield Zero
yield! Or' (And' data clock)
(And' (dff data clock) (Not' clock))
}
This is an issue with structural vs. referential equality.这是结构与引用平等的问题。 In F# seq { 'a' } = seq { 'a' } // false
but [ 'a' ] = [ 'a' ] // true
due to seq
being IEnumerable
and not supporting structural equality (or comparison).在 F# 中seq { 'a' } = seq { 'a' } // false
but [ 'a' ] = [ 'a' ] // true
因为seq
是IEnumerable
并且不支持结构相等(或比较)。 Lists (and other F# container-like types) are much more 'intelligent', ie they support structural equality / comparison if the contained objects support it:列表(和其他 F# 容器类类型)更加“智能”,即如果包含的对象支持,它们支持结构相等/比较:
[ {| foo = StringComparison.Ordinal; bar = Some(1.23) |} ] =
[ {| foo = StringComparison.Ordinal; bar = Some(1.23) |} ] // true
but don't, if they contain anything that doesn't: [ box(fun() -> 3) ] = [ box(fun() -> 3) ] // false
但不要,如果它们包含任何不包含的内容: [ box(fun() -> 3) ] = [ box(fun() -> 3) ] // false
So, to make the test work, add a List.ofSeq
:因此,为了使测试工作,添加一个List.ofSeq
:
dff Seq.empty Seq.empty |> List.ofSeq |> should equal [ Zero ]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.