3

如果我有一个无限序列,我不能使用正常的Seq.tryFind.

但是,如果序列是有序的,这意味着当我检测到序列中没有其他元素可以满足我的条件时,可以取消搜索。

有没有一种优雅的方式来表达这种搜索?

4

2 回答 2

5

如果您只想使用标准功能-这样的东西会起作用

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
于 2012-08-14T23:04:26.270 回答
3

这是另一种可能的解决方案。它与@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)
于 2012-08-14T23:19:41.680 回答