带有异步和选项的 F# 程序流问题

F# program flow question with Async and Option

我正在努力思考如何在 F# 中完成以下任务。以下是我要复制的简化 C# 伪代码等效项。

var x = await GetXAsync();
if (x == null) return "not found";
var y = await GetYAsync(x);
return y;

我的初始 F# 版本类似于:

task {
    let! x = GetXAsync()
    match x with
    | None -> // need to return a hard-coded value here
    | Some x` -> 
                 let! y = GetYAsync(x`)
                 // More code
                 // return some value based on y here
}

显然这很糟糕,但我不确定如何进行。我应该在这里尝试完整的 ROP 编程风格,还是有更简单的东西?

在您的示例中,您将返回 "not found" 字符串以指示函数出错,否则 returns 字符串。我不会这样做,因为很难区分一切正常的情况和不正常的情况。

如果 GetXAsync returns null 表明失败,那么我会使用例外。 F# async 对传播这些有很好的支持,您可以使用 try .. with 捕获它们。在F#中使用异常来处理异常情况没有错!

exception InvalidX of string

let GetXAsync() = async { 
  // whetever code that calculates 'failed' and 'result' goes here
  if failed then raise (InvalidX "not found")
  return result }

然后您可以调用函数,异常会自动传播。

async {
  let! x = GetXAsync() 
  let! y = GetYAsync(x)
  return y }