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)

または、ポイントフリースタイルが好きな場合(IMHOを読むのが難しくなるため、私はそうしません):

let has element = Seq.takeWhile ((>=) element) >> Seq.tryFind ((=) element)
于 2012-08-14T23:19:41.680 に答える