Skip to content

Instantly share code, notes, and snippets.

@shinnya
Last active March 20, 2018 21:37
Show Gist options
  • Save shinnya/16162da8eff39561eb84e5742dcfd023 to your computer and use it in GitHub Desktop.
Save shinnya/16162da8eff39561eb84e5742dcfd023 to your computer and use it in GitHub Desktop.
An example of FP testing using Continuation
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.2.8"
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.language.higherKinds
import scalaz.ContT
import scalaz.std.scalaFuture.futureInstance
object Main {
case class User(name: String, age: Int)
case class Sql(raw: String)
class Connection(host: String, port: Int) {
def open(): Future[Unit] = Future.successful(())
def close(): Future[Unit] = Future.successful(())
def execute(sql: Sql): Future[Int] = Future.successful(1)
}
def withUser[R](conn: Connection): ContT[Future, R, User] =
ContT(k => k(User("foo", 10)))
def withConnection[R](host: String, port: Int): ContT[Future, R, Connection] =
ContT { k =>
val conn = new Connection(host, port)
val ret = conn.open().flatMap(_ => k(conn))
ret.onComplete(_ => conn.close())
ret
}
def updateUser[R](conn: Connection, user: User): ContT[Future, R, Int] =
ContT(k => conn.execute(Sql(s"UPDATE t set age = ${user.age} WHERE name = ${user.name};")).flatMap(k))
def assert(p: => Boolean): Unit = if (p) () else throw new RuntimeException("")
def main(args: Array[String]): Unit = {
val future = (for {
conn <- withConnection[Unit]("localhost", 9999)
user <- withUser[Unit](conn)
affected <- updateUser[Unit](conn, user.copy(age = 30))
} yield assert(affected == 1)).run_
Await.result(future, 3.seconds)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment