@@ -3,74 +3,74 @@ package asyncstreams
33import scala .annotation .unchecked .{uncheckedVariance => uV }
44import scala .collection .GenIterable
55import scala .collection .generic .CanBuildFrom
6- import scala .concurrent .{ExecutionContext , Future }
76import scala .language .higherKinds
7+ import scalaz .Monad
8+ import scalaz .syntax .monad ._
89
9- case class AsyncStream [A ](data : Future [Step [A , AsyncStream [A ]]]) {
10+ case class AsyncStream [F [ + _] : Monad , A ](data : F [Step [A , AsyncStream [F , A ]]]) {
1011 import AsyncStream ._
1112
12- def foldLeft [B ](start : B )(f : (B , A ) => B )( implicit executor : ExecutionContext ) : Future [B ] = {
13- def impl (d : Future [Step [A , AsyncStream [A ]]], acc : Future [B ]): Future [B ] =
13+ def foldLeft [B ](start : B )(f : (B , A ) => B ): F [B ] = {
14+ def impl (d : F [Step [A , AsyncStream [F , A ]]], acc : F [B ]): F [B ] =
1415 d.flatMap {
1516 case END => acc
1617 case step => impl(step.rest.data, acc map (b => f(b, step.value)))
1718 }
1819
19- impl(data, Future ( start) )
20+ impl(data, start.point[ F ] )
2021 }
2122
22- def to [Col [_]](implicit executor : ExecutionContext , cbf : CanBuildFrom [Nothing , A , Col [A @ uV]]): Future [Col [A ]] =
23+ def to [Col [_]](implicit cbf : CanBuildFrom [Nothing , A , Col [A @ uV]]): F [Col [A ]] =
2324 foldLeft(cbf())((col, el) => col += el).map(_.result())
2425
2526
26- def takeWhile (p : A => Boolean )( implicit executor : ExecutionContext ) : AsyncStream [A ] =
27- new AsyncStream [A ](data map {
27+ def takeWhile (p : A => Boolean ): AsyncStream [F , A ] =
28+ new AsyncStream [F , A ](data map {
2829 case END => END
2930 case step if ! p(step.value) => END
3031 case step => Step (step.value, step.rest.takeWhile(p))
3132 })
3233
3334
34- def take (n : Int )( implicit executor : ExecutionContext ) : AsyncStream [A ] =
35+ def take (n : Int ): AsyncStream [F , A ] =
3536 if (n <= 0 ) nil
3637 else AsyncStream (data.map {
3738 case END => END
3839 case p => Step (p.value, p.rest.take(n - 1 ))
3940 })
4041
41- def foreach [U ](f : (A ) => U )( implicit executor : ExecutionContext ) : Future [Unit ] =
42+ def foreach [U ](f : (A ) => U ): F [Unit ] =
4243 foldLeft(())((_ : Unit , a : A ) => {f(a); ()})
4344
44- def foreachF [U ](f : (A ) => Future [U ])( implicit executor : ExecutionContext ) : Future [Unit ] =
45- foldLeft(Future (())) ((fu : Future [Unit ], a : A ) => fu.flatMap(_ => f(a)).map(_ => ())).flatMap(identity)
45+ def foreachF [U ](f : (A ) => F [U ]): F [Unit ] =
46+ foldLeft(().point[ F ]) ((fu : F [Unit ], a : A ) => fu.flatMap(_ => f(a)).map(_ => ())).flatMap(identity)
4647
47- def flatten [B ](implicit asIterable : A => GenIterable [B ], executor : ExecutionContext ): AsyncStream [B ] = {
48- val streamChunk = (p : Step [A , AsyncStream [A ]]) =>
49- concat(generate(asIterable(p.value))(it => if (it.nonEmpty) Future (it.head, it.tail) else ENDF ), p.rest.flatten)
48+ def flatten [B ](implicit asIterable : A => GenIterable [B ]): AsyncStream [F , B ] = {
49+ val streamChunk = (p : Step [A , AsyncStream [F , A ]]) =>
50+ concat(generate(asIterable(p.value))(it => if (it.nonEmpty) (it.head, it.tail).point[ F ] else ENDF [ F ] ), p.rest.flatten)
5051
5152 AsyncStream (data.flatMap {
52- case END => ENDF
53+ case END => ENDF [ F ]
5354 case step => streamChunk(step).data
5455 })
5556 }
5657}
5758
58-
5959object AsyncStream {
60- def nil [A ]( implicit executor : ExecutionContext ) : AsyncStream [A ] = AsyncStream (ENDF )
61- def single [A ](item : A )( implicit executor : ExecutionContext ) : AsyncStream [A ] =
62- AsyncStream (Future ( Step (item, nil[A ])) )
60+ def nil [F [ + _] : Monad , A ] : AsyncStream [F , A ] = AsyncStream (ENDF [ F ] )
61+ def single [F [ + _] : Monad , A ](item : A ): AsyncStream [F , A ] =
62+ AsyncStream (Step (item, nil[F , A ]).point[ F ] )
6363
64- def generate [S , A ](start : S )(gen : S => Future [(A , S )])( implicit executor : ExecutionContext ) : AsyncStream [A ] =
64+ def generate [F [ + _] : Monad , S , A ](start : S )(gen : S => F [(A , S )]): AsyncStream [F , A ] =
6565 AsyncStream (gen(start).map {
6666 case END => END
6767 case (el, rest) => Step (el, generate(rest)(gen))
6868 })
6969
70- def concat [A ](s1 : AsyncStream [A ], s2 : AsyncStream [A ])( implicit executor : ExecutionContext ) : AsyncStream [A ] =
71- new AsyncStream [A ](s1.data.flatMap {
70+ def concat [F [ + _] : Monad , A ](s1 : AsyncStream [F , A ], s2 : AsyncStream [F , A ]): AsyncStream [F , A ] =
71+ new AsyncStream [F , A ](s1.data.flatMap {
7272 case END => s2.data
73- case step => Future ( Step (step.value, concat(step.rest, s2)))
73+ case step => Step (step.value, concat(step.rest, s2)).point[ F ]
7474 })
7575}
7676
0 commit comments