@@ -4,73 +4,52 @@ import scala.annotation.unchecked.{uncheckedVariance => uV}
44import scala .collection .GenIterable
55import scala .collection .generic .CanBuildFrom
66import scala .language .higherKinds
7- import scalaz .Monad
8- import scalaz .syntax . monad . _
7+ import scalaz .syntax . monadPlus . _
8+ import scalaz .{ Monad , MonadPlus }
99
10- case class AsyncStream [F [+ _]: Monad , A ](data : F [Step [A , AsyncStream [F , A ]]]) {
11- import AsyncStream . _
10+ class AsyncStream [F [+ _]: Monad , A ](val data : F [Step [A , AsyncStream [F , A ]]]) {
11+ type SStep = Step [ A , AsyncStream [ F , A ]]
1212
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 ] =
15- d.flatMap {
16- case END => acc
17- case step => impl(step.rest.data, acc map (b => f(b, step.value)))
18- }
19-
20- impl(data, start.point[F ])
21- }
22-
23- def to [Col [_]](implicit cbf : CanBuildFrom [Nothing , A , Col [A @ uV]]): F [Col [A ]] =
24- foldLeft(cbf())((col, el) => col += el).map(_.result())
25-
26-
27- def takeWhile (p : A => Boolean ): AsyncStream [F , A ] =
28- new AsyncStream [F , A ](data map {
29- case END => END
30- case step if ! p(step.value) => END
31- case step => Step (step.value, step.rest.takeWhile(p))
32- })
13+ def to [Col [_]](implicit cbf : CanBuildFrom [Nothing , A , Col [A @ uV]], methods : ASImpl [F ]): F [Col [A ]] =
14+ methods.collectLeft(this )(cbf())((col, el) => col += el).map(_.result())
3315
16+ def takeWhile (p : A => Boolean )(implicit impl : ASImpl [F ]): AsyncStream [F , A ] = impl.takeWhile(this )(p)
3417
35- def take (n : Int ): AsyncStream [F , A ] =
36- if (n <= 0 ) nil
37- else AsyncStream (data.map {
38- case END => END
39- case p => Step (p.value, p.rest.take(n - 1 ))
40- })
18+ def take (n : Int )(implicit smp : MonadPlus [AsyncStream [F , ? ]]): AsyncStream [F , A ] =
19+ if (n <= 0 ) smp.empty
20+ else AsyncStream {
21+ data.map(p => Step (p.value, p.rest.take(n - 1 )))
22+ }
4123
42- def foreach [U ](f : (A ) => U ): F [Unit ] =
43- foldLeft (())((_ : Unit , a : A ) => {f(a); ()})
24+ def foreach [U ](f : (A ) => U )( implicit methods : ASImpl [ F ]) : F [Unit ] =
25+ methods.collectLeft( this ) (())((_ : Unit , a : A ) => {f(a); ()})
4426
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)
27+ def foreachF [U ](f : (A ) => F [U ])( implicit impl : ASImpl [ F ]) : F [Unit ] =
28+ impl.collectLeft( this ) (().point[F ])((fu : F [Unit ], a : A ) => fu.flatMap(_ => f(a)).map(_ => ())).flatMap(identity)
4729
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)
30+ def flatten [B ](implicit asIterable : A => GenIterable [B ], smp : MonadPlus [ AsyncStream [ F , ? ]], impl : ASImpl [ F ] ): AsyncStream [F , B ] = {
31+ def streamChunk ( step : AsyncStream [ F , A ] # SStep ) : AsyncStream [F , B ] =
32+ impl.fromIterable( asIterable(step .value).seq) <+> step. rest.flatten
5133
52- AsyncStream (data.flatMap {
53- case END => ENDF [F ]
54- case step => streamChunk(step).data
55- })
34+ AsyncStream (data.flatMap(step => streamChunk(step).data))
5635 }
36+
37+ def isEmpty (implicit impl : ASImpl [F ]): F [Boolean ] = impl.isEmpty(this )
38+ def nonEmpty (implicit impl : ASImpl [F ]): F [Boolean ] = impl.isEmpty(this ).map(! _)
5739}
5840
5941object AsyncStream {
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 ])
42+ def apply [F [+ _]: Monad , A ](data : => F [Step [A , AsyncStream [F , A ]]]): AsyncStream [F , A ] = new AsyncStream (data)
43+ def asyncNil [F [+ _]: Monad , A ](implicit impl : ASImpl [F ]): AsyncStream [F , A ] = impl.empty
6344
64- def generate [F [+ _]: Monad , S , A ](start : S )(gen : S => F [(A , S )]): AsyncStream [F , A ] =
65- AsyncStream (gen(start).map {
66- case END => END
67- case (el, rest) => Step (el, generate(rest)(gen))
68- })
45+ private [asyncstreams] def generate [F [+ _]: Monad , S , A ](start : S )(gen : S => F [(S , A )])(implicit smp : MonadPlus [AsyncStream [F , ? ]]): AsyncStream [F , A ] = AsyncStream {
46+ gen(start).map((stateEl : (S , A )) => Step (stateEl._2, generate(stateEl._1)(gen)))
47+ }
6948
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 {
72- case END => s2.data
73- case step => Step (step.value, concat(step.rest, s2)).point[F ]
74- })
75- }
49+ def unfold [F [+ _]: Monad , T ](start : T )(makeNext : T => T )(implicit smp : MonadPlus [AsyncStream [F , ? ]]): AsyncStream [F , T ] =
50+ generate(start)(s => (makeNext(s), s).point[F ])
7651
52+ implicit class AsyncStreamOps [F [+ _]: Monad , A ](stream : => AsyncStream [F , A ]) {
53+ def ~:: (el : A ) = AsyncStream (Step (el, stream).point[F ])
54+ }
55+ }
0 commit comments