fix TaskBuilder.TryFinally -- fixes #348#349
Conversation
1f7aa39 to
b999db3
Compare
|
Hi, I applaud you for actually contributing changes (rather than just whining like me). I can answer your second question at least: the type signatures in the doc are really just suggestions. All that matters is that everything typechecks after the compiler desugars the computation expression to method calls. This means you can use a separate type to represent a delayed expression as long as the methods that will take delayed expressions handle that type. For example, the body of a while loop is always delayed, so while you could write (as the docs suggest): member __.Delay(computation : unit -> M<'t>) = ... : M<'t>
member __.While(cond : unit -> bool, delayedBody : M<unit>) = ... : M<unit>This approach works just as well (as long as you don't need any special custom behavior for your delayed exprs), and is probably the most common way to do it: member __.Delay(computation : unit -> M<'t>) = computation
member __.While(cond : unit -> bool, delayedBody : unit -> M<unit>) = ... : M<unit>
// ^^^^^^^^^^^^^^^
// notice the type matches delay's return type
Anyway, from skimming your contribution, I think you fell victim to a bug that I also had with my own TaskBuilder implementation. If try
()
finally
printfn "ran!" // I think this will get printed twice.
failwith "uhoh"I think if you just move the // instead of
// this.TryWith((fun () -> this.Bind(m(), wrapOk)), wrapCrash)
this.Bind(this.TryWith(m, wrapCrash), wrapOk) |
50a04f9 to
d16572e
Compare
|
@rspeele thanks so much for spotting the mistake and the general overview! I think I'm getting now much better what's going on. |
|
@forki @mausch @panesofglass ping |
Fixes the uses of `use` keyword in `TaskBuilder` and other constructs that use `TryFinally`. Before, `TryFinally` called compensation (disposing) immediately. Now the compensation (disposing) is called only after the body runs. fixes fsprojects#348
d16572e to
9e0b9fd
Compare
|
thx |

Fixes the uses of
usekeyword inTaskBuilderand other constructs that useTryFinally.Before,
TryFinallycalled compensation (disposing) immediately.Now the compensation (disposing) is called only after the body runs.
fixes #348