Why does the calculation expression not cover the finally block

For example:

let test () = async { try do! someting () finally do! sometingElse () } 

You can't do do! in that, finally, you get a message from the compiler, "you can use do! in the expression of the calculation", but it is still there right.

I know how I can solve this, but I would like to understand why the compiler restricts this scenario.

Well after some fiddeling, I think it was so discouraged: (I am very happy that we can write cexprs)

from

 async { try do! someting () do! sometingElse () finally printfn "finally" } 

in

 async.TryFinally( async.Bind( someting(), (fun () -> async.Bind(sometingElse (), (fun () -> async.Zero())))), (fun () -> printfn "finally")) |> ignore 

I get that the second part of TryFinally does not support cexpr .

+8
f #
source share
1 answer

As discussed in the question, try-finally expressions with a calculation expression for the finally clause are simply not supported (in F # 3.1). However, it is easy to implement a function that essentially has this behavior. Here is an example implementation:

 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 } 
+7
source share

All Articles