fsharp.core.extensions
fsharp.core.extensions copied to clipboard
Added `AsyncSeq.recoverWith`
let recoverWith (f: exn -> AsyncSeq<'a>) (upstream: AsyncSeq<'a>): AsyncSeq<'a> =
let e = upstream.GetAsyncEnumerator()
{ new AsyncSeq<'a> with
member __.GetAsyncEnumerator (cancel) =
let outer = upstream.GetAsyncEnumerator(cancel)
let mutable inner = Unchecked.defaultof<IAsyncEnumerator<'a>>
{ new IAsyncEnumerator<'a> with
member __.Current =
if isNull inner
then outer.Current
else inner.Current
member __.DisposeAsync() = unitVtask {
let mutable step = 0
try
do! outer.DisposeAsync()
step <- 1
if not (isNull inner) then
do! inner.DisposeAsync()
step <- 2
with ex ->
if step < 2 then
do! inner.DisposeAsync()
return rethrow ex
}
member __.MoveNextAsync() = vtask {
if isNull inner then
try
return! outer.MoveNextAsync()
with ex ->
inner <- (f ex).GetAsyncEnumerator(cancel)
return! inner.MoveNextAsync()
else return! inner.MoveNextAsync()
} }}
This should be handy, for recovering from errors.