在 F# 中是否有更惯用的方法来实现这些顺序测试

is there a more idiomatic way to achive these sequential test, in F#

我有一个函数(我们称它为 'doSomething')returns:

('a * 'b) option

并希望实现这样的目标:

let testA = doSomething ....
if testA.IsSome then return testA.Value
let testB = doSomething ....
if testB.IsSome then return testB.Value
let testC = doSomething ....
if testC.IsSome then return testC.Value

我正在寻找一个计算表达式或等效的简单语法,它会在结果为 None 时继续执行,但保留第一个结果。

显然我想避免 while if / elif / elif / ... / elif / else 厄运金字塔。

一个选择(呵呵呵)是将来自 Option 模块的一些调用链接在一起,如下所示:

let doSomething doThisOne tup = if doThisOne then Some tup else None

let f () =
    doSomething false (1, 2)
    |> Option.orElseWith (fun () -> doSomething false (2, 3))
    |> Option.orElseWith (fun () -> doSomething true (3, 4))
    |> Option.defaultValue (0, 0)

f () // Evaluates to (3, 4)

可能能够使用FsToolkit.ErrorHandling和option CE的应用语法,但我不知道有什么好的结合方法结果看起来像,所以我个人会像上面那样进行链式调用。

我将其视为惯用的管道:

[
  "test01";
  "test02";
  ...
]
(* |> Seq.ofList - unnecessary, as noted in the comments *)
|> Seq.tryPick doSomething (* sequentially calls 'doSomething' with test params and returns the first result of 'Some(x)' *)