@@ -3,74 +3,74 @@ package asyncstreams
3
3
import scala .annotation .unchecked .{uncheckedVariance => uV }
4
4
import scala .collection .GenIterable
5
5
import scala .collection .generic .CanBuildFrom
6
- import scala .concurrent .{ExecutionContext , Future }
7
6
import scala .language .higherKinds
7
+ import scalaz .Monad
8
+ import scalaz .syntax .monad ._
8
9
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 ]]]) {
10
11
import AsyncStream ._
11
12
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 ] =
14
15
d.flatMap {
15
16
case END => acc
16
17
case step => impl(step.rest.data, acc map (b => f(b, step.value)))
17
18
}
18
19
19
- impl(data, Future ( start) )
20
+ impl(data, start.point[ F ] )
20
21
}
21
22
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 ]] =
23
24
foldLeft(cbf())((col, el) => col += el).map(_.result())
24
25
25
26
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 {
28
29
case END => END
29
30
case step if ! p(step.value) => END
30
31
case step => Step (step.value, step.rest.takeWhile(p))
31
32
})
32
33
33
34
34
- def take (n : Int )( implicit executor : ExecutionContext ) : AsyncStream [A ] =
35
+ def take (n : Int ): AsyncStream [F , A ] =
35
36
if (n <= 0 ) nil
36
37
else AsyncStream (data.map {
37
38
case END => END
38
39
case p => Step (p.value, p.rest.take(n - 1 ))
39
40
})
40
41
41
- def foreach [U ](f : (A ) => U )( implicit executor : ExecutionContext ) : Future [Unit ] =
42
+ def foreach [U ](f : (A ) => U ): F [Unit ] =
42
43
foldLeft(())((_ : Unit , a : A ) => {f(a); ()})
43
44
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)
46
47
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)
50
51
51
52
AsyncStream (data.flatMap {
52
- case END => ENDF
53
+ case END => ENDF [ F ]
53
54
case step => streamChunk(step).data
54
55
})
55
56
}
56
57
}
57
58
58
-
59
59
object 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 ] )
63
63
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 ] =
65
65
AsyncStream (gen(start).map {
66
66
case END => END
67
67
case (el, rest) => Step (el, generate(rest)(gen))
68
68
})
69
69
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 {
72
72
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 ]
74
74
})
75
75
}
76
76
0 commit comments