Skip to content

Commit 4afba84

Browse files
committed
AsyncSeq.interleave
1 parent eb68b52 commit 4afba84

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

src/FSharpx.Async/AsyncSeq.fs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,25 @@ module AsyncSeq =
506506
yield item
507507
yield! concatSeq tl }
508508

509+
/// Interleaves two async sequences into a resulting sequence. The provided
510+
/// sequences are consumed in lock-step.
511+
let interleave =
512+
513+
let rec left (a:AsyncSeq<'a>) (b:AsyncSeq<'b>) : AsyncSeq<Choice<_,_>> = async {
514+
let! a = a
515+
match a with
516+
| Cons (a1, t1) -> return Cons (Choice1Of2 a1, right t1 b)
517+
| Nil -> return! b |> map Choice2Of2 }
518+
519+
and right (a:AsyncSeq<'a>) (b:AsyncSeq<'b>) : AsyncSeq<Choice<_,_>> = async {
520+
let! b = b
521+
match b with
522+
| Cons (a2, t2) -> return Cons (Choice2Of2 a2, left a t2)
523+
| Nil -> return! a |> map Choice1Of2 }
524+
525+
left
526+
527+
509528
[<AutoOpen>]
510529
module AsyncSeqExtensions =
511530
/// Builds an asynchronou sequence using the computation builder syntax

tests/FSharpx.Async.Tests/AsyncSeqTests.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,11 @@ let ``unfoldAsync should generate a sequence``() =
7676
Assert.True(([0;1;2] = s))
7777

7878

79+
80+
[<Test>]
81+
let ``Interleave should interleave two sequences``() =
82+
let s1 = AsyncSeq.ofSeq ["a";"b";"c"]
83+
let s2 = AsyncSeq.ofSeq [1;2;3]
84+
let merged = AsyncSeq.interleave s1 s2 |> AsyncSeq.toList |> Async.RunSynchronously
85+
printfn "%A" merged
86+
Assert.True([Choice1Of2 "a" ; Choice2Of2 1 ; Choice1Of2 "b" ; Choice2Of2 2 ; Choice1Of2 "c" ; Choice2Of2 3] = merged)

0 commit comments

Comments
 (0)