我刚刚在F#中发现了一些我称之为怪癖的东西,并且想知道它是设计还是错误,如果是设计,为什么会如此...如果你写第一个术语的任何范围表达式大于第二项,返回的序列为空.看看反射器表明这是设计的,但我无法找到它必须如此的原因.重现它的一个例子是:
[1..10] |> List.length
[10..1] |> List.length
Run Code Online (Sandbox Code Playgroud)
第一个将打印出10,而第二个将打印出0.测试在F#CTP 1.9.6.2中进行.
编辑:感谢您建议明确范围,但仍然有一个案例(这是启发我提出这个问题的原因)将不会被涵盖.如果A和B是变量并且没有一个比其他变量更大,尽管它们总是不同的怎么办?考虑到范围表达式似乎在编译时似乎没有得到优化,是否有任何充分的理由来确定步骤(未明确指定)的代码,如果A和B是不允许负步骤的情况?
Bri*_*ian 13
正如其他答案所建议的那样,你可以做到
[10 .. -1 .. 1] |> List.iter (printfn "%A")
Run Code Online (Sandbox Code Playgroud)
例如
[start .. step .. stop]
Run Code Online (Sandbox Code Playgroud)
Adam Wright - 但是您应该能够更改您感兴趣的类型的绑定,以您喜欢的任何方式运行(包括如果 x > y 则倒计时)。
将 Adam 的建议写入代码:
let (..) a b =
if a < b then seq { a .. b }
else seq { a .. -1 .. b }
printfn "%A" (seq { 1 .. 10 })
printfn "%A" (seq { 10 .. 1 })
Run Code Online (Sandbox Code Playgroud)
这适用于 int 范围。查看 (..) 的源代码:您也许可以使用它来处理其他类型的范围,但不确定如何为您的特定类型获得正确的 -1 值。