Created
November 7, 2018 15:53
-
-
Save chrilves/955e433b89c397ebb0046375b43d3386 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.language.higherKinds | |
import scala.language.implicitConversions | |
import scala.util.Random | |
import scala.concurrent.Future | |
import scala.concurrent.ExecutionContext.Implicits._ | |
/** A simple trait telling how to save in DB */ | |
sealed trait DBMode { | |
type Op[_] | |
def saveInDB[A](a: A): Op[A] | |
} | |
/** This mode indicate we don't want to commit. | |
* We just pass the value as-is. | |
*/ | |
case object DoNotCommit extends DBMode { | |
type Op[X] = X | |
def saveInDB[A](a: A): A = a | |
} | |
/** This mode is for synchronous commits. | |
* We want to wait for the commit to end. | |
* It may fail so we return an option. | |
*/ | |
case object CommitSync extends DBMode { | |
type Op[X] = Option[X] | |
def saveInDB[A](a: A): Option[A] = | |
if (Random.nextBoolean) | |
Some(a) | |
else | |
None | |
} | |
/** This mode is for asynchronous commits. | |
* We don't wait for the commit to end. | |
* Instead we launch a Future. | |
* It may also fail so we return an option. | |
*/ | |
case object CommitAsync extends DBMode { | |
type Op[X] = Future[Option[X]] | |
def saveInDB[A](a: A): Future[Option[A]] = { | |
println("[CommitAsync] Before operation") | |
val ret = | |
Future { | |
println("[CommitAsync] Start operation") | |
if (scala.util.Random.nextBoolean) | |
Some(a) | |
else | |
None | |
} | |
println("[CommitAsync] After operation") | |
ret | |
} | |
} | |
/** Here is the complete function taking the value and | |
* the DBMode. The return type depends on the mode. | |
*/ | |
def saveInDB[A](a: A, dbMode: DBMode): dbMode.Op[A] = | |
dbMode.saveInDB(a) | |
/* In each of the following cases, the only difference is the mode we invoke. */ | |
val anInt : Int = saveInDB(5, DoNotCommit) | |
val anOptionIint : Option[Int] = saveInDB(5, CommitSync ) | |
val aFutureOptionInt : Future[Option[Int]] = saveInDB(5, CommitAsync) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment