如果我有一个无限序列,我不能使用正常的Seq.tryFind
.
但是,如果序列是有序的,这意味着当我检测到序列中没有其他元素可以满足我的条件时,可以取消搜索。
有没有一种优雅的方式来表达这种搜索?
如果您只想使用标准功能-这样的东西会起作用
let evens = Seq.initInfinite ((*)2)
let has v =
Seq.tryPick (fun x ->
if x = v then Some (Some v)
elif x > v then Some None
else None)
>> Option.bind id
has 40 evens // Some 40
has 41 evens // None
这是另一种可能的解决方案。它与@desco 发布的内容非常相似,但它使用的是序列表达式而不是Seq.tryPick
并且它也不需要嵌套选项类型:
let has element input =
seq { for v in input do
if v = element then yield Some v
if v > element then yield None }
|> Seq.head
甚至使用内置函数的更好更简单的解决方案。只需使用Seq.takeWhile
仅包含小于或等于您要查找的元素的序列的开头,然后Seq.tryFind
在序列的这一部分使用:
let has element input =
input |> Seq.takeWhile (fun x -> x <= element)
|> Seq.tryFind (fun x -> x = element)
或者,如果您喜欢无点风格(我不喜欢,因为它更难阅读恕我直言):
let has element = Seq.takeWhile ((>=) element) >> Seq.tryFind ((=) element)