FSharp.Control.TaskSeq icon indicating copy to clipboard operation
FSharp.Control.TaskSeq copied to clipboard

Documentation says there's a `TaskSeq.toAsyncSeq` function, but it does not exist

Open abelbraaksma opened this issue 2 years ago • 3 comments

Can we implement this function? To prevent having a dependency on AsyncSeq, we probably need to create this function using SRTP, but it should be possible for users to convert to/from AsyncSeq.

abelbraaksma avatar Dec 19 '23 18:12 abelbraaksma

I needed this internally and came up with this implementation:

#r "nuget: FSharp.Control.TaskSeq, 0.4.0"
#r "nuget: FSharp.Control.AsyncSeq, 3.2.1"

open FSharp.Control

[<RequireQualifiedAccess>]
module TaskSeq =

  let toAsyncSeq (xs : TaskSeq<'a>) : AsyncSeq<'a> =
    asyncSeq {
      let! ct = Async.CancellationToken

      let en = xs.GetAsyncEnumerator(ct)

      try
        while! en.MoveNextAsync().AsTask() |> Async.AwaitTask do
          yield en.Current
      finally
        en.DisposeAsync().AsTask()
        |> Async.AwaitTask
        |> Async.RunSynchronously
    }

let main () =
  let input =
    taskSeq {
      yield "h"
      yield "e"
      yield "l"
      yield "l"
      yield "o"
      yield " "
      yield "w"
      yield "o"
      yield "r"
      yield "l"
      yield "d"
    }

  let output =
    input
    |> TaskSeq.toAsyncSeq

  async {
    for x in output do
      printfn $"%s{x}"
  }
  |> Async.RunSynchronously

main ()

Any gotchas I have missed?

The dispose logic feels nasty.

Happy to send a PR.

njlr avatar Oct 24 '25 12:10 njlr

@njlr thanks, as a quick look, this looks like a fine approach. However, we wouldn't want to have a dependency on AsyncSeq, that would be bad practice. Currently, this lib has zero dependencies and I like it that way.

The inverse is, as you've mentioned, easier, because the IAsyncEnumerable<'T> type is part of the .NET standard library. But the AsyncSeq library does not use a common interface that I could use.

I haven't looked at this for a while, I should probably get back into it.

abelbraaksma avatar Nov 14 '25 12:11 abelbraaksma

Happy to make a PR to https://github.com/fsprojects/FSharp.Control.AsyncSeq for this

Perhaps names reversed? AsyncSeq.ofTaskSeq

njlr avatar Nov 14 '25 13:11 njlr