Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created September 19, 2014 14:10
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xuwei-k/756ae67f1f5563fbf265 to your computer and use it in GitHub Desktop.
Save xuwei-k/756ae67f1f5563fbf265 to your computer and use it in GitHub Desktop.
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.1.0"
//libraryDependencies += "org.typelevel" %% "scalaz-contrib-210" % "0.1.5" // for scalaz 7.0.x
scalaVersion := "2.10.4"
package either_and_future_sample
import scalaz._
import scala.concurrent.{ExecutionContext, Future}
import scalaz.std.scalaFuture._ // for scalaz 7.1.0
// import scalaz.contrib.std.scalaFuture._ // for scalaz 7.0.x
import either_and_future_sample.Main.{UserId, context}
sealed trait Error
/** 引数であたえられたUserIdのUserが、そもそも存在しなかった場合 */
final case class UserNotFound(userId: UserId) extends Error
/** データベースにつながらなかったとか、そういうの */
final case class ConnectionError(message: String) extends Error
final case class User(id: UserId, name: String)
object UsersRepository {
def followers(userId: UserId): Future[Either[Error, List[User]]] = {
// 失敗した場合に、次のものが呼ばれるかどうか?をわかりやすくするために、printして、かつ失敗を固定で返す
println("call followers " + userId)
Future.successful(Left(UserNotFound(userId)))
}
def isFriends1(user1: UserId, user2: UserId): Future[Either[Error, Boolean]] =
for{
a <- followers(user1)
b <- followers(user2)
} yield for {
x <- a.right
y <- b.right
} yield x.exists(_.id == user2) && y.exists(_.id == user1)
def isFriends2(user1: UserId, user2: UserId): Future[Either[Error, Boolean]] =
followers(user1).flatMap{
case Right(a) =>
followers(user2).map{
case Right(b) =>
Right(a.exists(_.id == user2) && b.exists(_.id == user1))
case Left(e) =>
Left(e)
}
case Left(e) =>
Future.successful(Left(e))
}
}
object UsersRepositoryScalaz {
def followers(userId: UserId): EitherT[Future, Error, List[User]] = {
// 失敗した場合に、次のものが呼ばれるかどうか?をわかりやすくするために、printして、かつ失敗を固定で返す
println("call followers " + userId)
EitherT.left(Future.successful(UserNotFound(userId)))
}
def isFriends3(user1: UserId, user2: UserId): EitherT[Future, Error, Boolean] =
for{
a <- followers(user1)
b <- followers(user2)
} yield a.exists(_.id == user2) && b.exists(_.id == user1)
}
object Main {
// ダミーの、単一スレッドでだけ使うExecutionContext
implicit val context: ExecutionContext = new ExecutionContext {
override def execute(runnable: Runnable): Unit = runnable.run()
override def reportFailure(t: Throwable): Unit = t.printStackTrace()
}
type UserId = Long
def main(args: Array[String]) {
println("isFriends1")
UsersRepository.isFriends1(0, 1)
println
println("isFriends2")
UsersRepository.isFriends2(0, 1)
println
println("isFriends3 scalaz")
UsersRepositoryScalaz.isFriends3(0, 1)
println
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment