/
Iteratee.scala
56 lines (42 loc) · 1.33 KB
/
Iteratee.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package scala.slick.util.iter
import scala.slick.SlickException
/**
* An iteratee for DB results.
*/
sealed trait IterV[E, +A] {
def runOption: Option[A]
def run = runOption.getOrElse(throw new SlickException("Diverging iteratee"))
def map[B](f: A => B): IterV[E, B]
def flatMap[B](f: A => IterV[E, B]): IterV[E, B]
}
case class Done[E, +A](a: A, e: Input[E] = Empty) extends IterV[E, A] {
def runOption = Some(a)
def map[B](f: A => B): IterV[E, B] = Done(f(a), e)
def flatMap[B](f: A => IterV[E, B]) = f(a) match {
case Done(x, _) => Done(x, e)
case Cont(k) => k(e)
}
}
case class Cont[E, +A](k: Cont.K[E, A]) extends IterV[E, A] {
def runOption = k(EOF) match {
case Done(a, _) => Some(a)
case Cont(_) => None
}
def map[B](f: A => B): IterV[E, B] = Cont { i => k(i).map(f) }
def flatMap[B](f: A => IterV[E, B]) = Cont { i => k(i).flatMap(f) }
}
object Cont {
type K[E, +A] = Input[E] => IterV[E, A]
}
sealed trait Input[+E] {
def fold[R](el: E => R, empty: => R, eof: => R): R
}
case class El[+E](e: E) extends Input[E] {
def fold[R](el: E => R, empty: => R, eof: => R): R = el(e)
}
case object Empty extends Input[Nothing] {
def fold[R](el: Nothing => R, empty: => R, eof: => R): R = empty
}
case object EOF extends Input[Nothing] {
def fold[R](el: Nothing => R, empty: => R, eof: => R): R = eof
}