How to deal with rollbacks when using the Either monad ("railway-oriented programming")
<p>I am using F# and Chessie to compose a sequence of tasks (with side effects) that can succeed or fail.</p>

<p>If anything fails, I want to stop executing the remaining tasks and rollback those that have already succeeded.</p>

<p>Unfortunately once I hit the 'failure' path there is no longer a way to retrieve the results of the successful tasks so I can roll them back.</p>

<p>Is there a functional programming "pattern" that deals with this scenario?</p>

<p>Example:</p>

<pre><code>let refuel =
  async {
    printfn "1 executed"
    // Fill missile with fuel
    return Result&lt;string,string&gt;.Succeed "1"
  }  |&gt; AR

let enterLaunchCodes =
  async {
    printfn "2 executed"
    // 
    return Result&lt;string,string&gt;.FailWith "2"
  }  |&gt; AR

let fireMissile =
  async {
    printfn "3 executed"
    return Result&lt;string,string&gt;.Succeed "3"
  } |&gt; AR

let launchSequence =
  asyncTrial {
    let! a = refuel
    let! b = enterLaunchCodes
    let! c = fireMissile
    return a,b,c
  }

let result = launchSequence
    |&gt; Chessie.ErrorHandling.AsyncExtensions.Async.ofAsyncResult
    |&gt; Async.RunSynchronously

// Result is a failure... how do I know the results of the successful operations here so I can roll them back?

printfn "Result: %A" result
</code></pre>