使用let有一些限制!里面的比赛声明?我不确定为什么这不会编译.
module Foo =
let Bar =
async {
let result =
match 1 with
| 1 ->
let! num = async.Return 12345 // Doesn't compile
1
| _ -> 2
return result
}
Run Code Online (Sandbox Code Playgroud)
编译失败,"此构造只能在计算表达式中使用"
Tom*_*cek 10
如前所述,问题在于异步工作流只允许某些类型的嵌套 - 您不能let!在普通表达式中使用,而只能在计算表达式中使用.在您的例子的问题是不是真的match,但let(包含match).为了更好地了解发生了什么,规范(粗略地)看起来如下:
cexpr:= 让!x = expr in cexpr
| 让 X = EXPR 在 cexpr
| 返回! expr
| (......)
关键是参数只是一个普通的表达式expr和正文跟随let或是let!另一个可以包含更多异步操作的计算表达式.
所以,如果你有let x = e1 in e2,那么你只能let!在e2,但不是e1.
在实践中,您可以执行Daniel建议并使用嵌套异步工作流,或者您可以重写代码,以便需要异步的代码不会使用等待内部表达式,这是不可能的 - 很难说如何做一般情况下,但在您的具体示例中,您可以写:
let bar = async {
match 1 with
| 1 ->
let! num = async.Return 12345
return 1
| _ ->
return 2 }
Run Code Online (Sandbox Code Playgroud)
对Bind(via let!)的调用必须出现在计算表达式的顶层.您可以通过创建嵌套async { }块来修复它:
module Foo =
let Bar =
async {
let result = async {
match 1 with
| 1 ->
let! num = async.Return 12345
return 1
| _ -> return 2
}
return result
}
Run Code Online (Sandbox Code Playgroud)