aboutsummaryrefslogtreecommitdiff
path: root/tests/bench/transactional/ReaderMonadic.scala
diff options
context:
space:
mode:
Diffstat (limited to 'tests/bench/transactional/ReaderMonadic.scala')
-rw-r--r--tests/bench/transactional/ReaderMonadic.scala87
1 files changed, 87 insertions, 0 deletions
diff --git a/tests/bench/transactional/ReaderMonadic.scala b/tests/bench/transactional/ReaderMonadic.scala
new file mode 100644
index 000000000..ce69c35ad
--- /dev/null
+++ b/tests/bench/transactional/ReaderMonadic.scala
@@ -0,0 +1,87 @@
+package transactional
+
+case class Reader[R,A](run: R => A) {
+ def map[B](f: A => B): Reader[R, B] = Reader(r => f(run(r)))
+ def flatMap[B](f: A => Reader[R, B]): Reader[R, B] = Reader(r => f(run(r)).run(r))
+}
+
+object Reader {
+ def ask[R]: Reader[R,R] = Reader(r => r)
+}
+
+object ReaderBench extends Benchmark {
+ type Transactional[T] = Reader[Transaction, T]
+
+ def transaction[T](op: Transactional[T]): T = {
+ implicit val trans: Transaction = new Transaction
+ val res = op.run(trans)
+ trans.commit()
+ res
+ }
+
+ def thisTransaction: Transactional[Transaction] = Reader.ask
+
+ abstract class Op {
+ def f(x: Int): Transactional[Int]
+ }
+
+ class Op0 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("0th step"); x }
+ }
+
+ class Op1 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("first step"); x + 1 }
+ }
+
+ class Op2 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("second step"); x + 2 }
+ }
+
+ class Op3 extends Op {
+ def f(x: Int): Transactional[Int] =
+ for (trans <- thisTransaction)
+ yield { trans.println("third step"); x + 3 }
+ }
+
+ val op = Array[Op](new Op0, new Op1, new Op2, new Op3)
+
+ def f(x: Int, n: Int): Transactional[Int] = {
+ def rest(trans: Transaction): Transactional[Int] = {
+ trans.println("fourth step")
+ if (n > 0) {
+ for {
+ y <- op(n % 4).f(x)
+ z <- f(y: Int, n - 1)
+ }
+ yield z
+ }
+ else {
+ if (x % 2 != 0)
+ for (trans <- thisTransaction)
+ yield { trans.abort(); () }
+ Reader(_ => x)
+ }
+ }
+ thisTransaction.flatMap(rest)
+ }
+
+ def run(): Int = {
+ transaction {
+ for (res <- f(7, 10))
+ yield {
+ for (trans <- thisTransaction)
+ yield { assert(!trans.isAborted); () }
+ assert(res == 22)
+ res
+ }
+ }
+ }
+}
+
+object ReaderMonadic extends Runner("reader monadic", ReaderBench, 22)