Skip to content

Instantly share code, notes, and snippets.

@chrilves
Created November 7, 2018 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrilves/955e433b89c397ebb0046375b43d3386 to your computer and use it in GitHub Desktop.
Save chrilves/955e433b89c397ebb0046375b43d3386 to your computer and use it in GitHub Desktop.
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