gpt4 book ai didi

F#序列比较

转载 作者:行者123 更新时间:2023-12-03 23:53:09 25 4
gpt4 key购买 nike

我已经实现了一个斐波那契数列发生器如下

let getNext upperLimit current= 
let (e1, e2) = current
let next = e1 + e2
if next > upperLimit then None
else Some (next, (e2,next))

let fib upperLimit = (0,1) |> Seq.unfold (getNext upperLimit) |> Seq.append [0;1]

我的测试代码是
[<Test>]
member Spec.``fib not exeeding 20 should be 0,1,1,2,3,5,8,13``()=
let expected = seq [0;1;1;2;3;5;8;13]
let result = fib 20
let expectedSameAsResult = (expected = result)
printfn "Expected: %A Result: %A result length: %d" expected result (Seq.length result)
Assert.That expectedSameAsResult

测试失败,打印结果为

预期:[0; 1; 1; 2; 3; 5; 8; 13] 结果:seq [0; 1; 1; 2; ...] 结果长度:8

当我使用 for 循环打印结果中的每个元素时,我在预期的序列中得到了完全相同的元素。

那么,预期和结果序列之间有什么区别?

编辑:我的实现可以在 https://github.com/weima/EulerProblems/tree/master/EulerProblems 找到

编辑:回答约翰·帕默的回答
我刚刚在 F# 交互式窗口中写了一个测试
 let a = seq[1;2;3]
let b = seq[1;2;3]
let c = a = b;;

我得到的结果是
val a : seq = [1; 2; 3]
val b : seq = [1; 2; 3]
val c : bool = true

所以 F# 也可以对序列进行结构比较。

编辑以反射(reflect) Gene Belitski 的回答
我已将测试更改为
[<Test>]
member Spec.``fib not exeeding 20 should be 0,1,1,2,3,5,8,13``()=
let expected = seq [0;1;1;2;3;5;8;13]
let result = Problem2.fib 20
let comparedResult = Seq.compareWith (fun a b -> a - b) expected result
let expectedSameAsResult = (comparedResult = 0)
Assert.That expectedSameAsResult

现在它起作用了。谢谢!但我仍然不明白为什么一个简单的 seq[1;2;3]=seq[1;2;3] 有效,但我的测试用例没有。

最佳答案

虽然您可能会期望 a=b将比较它实际上的序列的元素 a=b计算引用相等。

你可以用类似的东西看到这个

seq {1..3} = seq {1..3}

返回false。

但是,在某些情况下,当您使用常量时,您会得到令人困惑的结果,尤其是
seq [1;2;3] = seq [1;2;3]

返回true,这令人困惑。

为了避免这个问题,你需要做类似的事情
 let test a b = Seq.fold (&&) true (Seq.zip a b |> Seq.map (fun (aa,bb) -> aa=bb))

比较元素明智。

或者,您可以使用 Seq.compareWith如 Gene 的回答所述。但是,这要求元素还实现比较运算符以及相等性,这对于实现 = 的可区分联合等某些事情可能并非如此。但不是比较。

关于F#序列比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17101329/

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