例如:
let test () =
async {
try
do! someting ()
finally
do! sometingElse ()
}
Run Code Online (Sandbox Code Playgroud)
你不能做到do!最后你从编译器得到消息"你只能在计算表达式中使用do!"但它仍然在那里.
我知道如何解决这个问题,但我想了解编译器限制这种情况的原因.
好了一些fiddeling后,我觉得它像这样沮丧:(我很高兴我们可以写cexprs)
从:
async {
try
do! someting ()
do! sometingElse ()
finally
printfn "finally"
}
Run Code Online (Sandbox Code Playgroud)
至:
async.TryFinally(
async.Bind(
someting(), (fun () ->
async.Bind(sometingElse (), (fun () ->
async.Zero())))), (fun () -> printfn "finally")) |> ignore
Run Code Online (Sandbox Code Playgroud)
我知道第二部分TryFinally不支持a cexpr.
小智 7
正如问题中已经讨论过的那样,根本不支持try-finally带有finally子句计算表达式的表达式(在F#3.1中).但是,很容易实现具有这种行为的功能.这是一个示例实现:
let tryFinally (body: Async<'x>) (finalize: Async<unit>) : Async<'x> = async {
let! result = Async.Catch body
do! finalize
return match result with
| Choice1Of2 value -> value
| Choice2Of2 exn -> raise exn
}
Run Code Online (Sandbox Code Playgroud)