Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Last active January 4, 2016 18:49
Show Gist options
  • Save xuwei-k/8662956 to your computer and use it in GitHub Desktop.
Save xuwei-k/8662956 to your computer and use it in GitHub Desktop.

解説

  • A[B[C]] という型のオブジェクトがあったときにATraverseBApplicativeならば、sequenceという関数を呼ぶだけで、 A[B[C]] から B[A[C]] に変換できます。

  • OptionTraverse であり、FutureApplicative です。

  • なので、 Option[Future[A]]Future[Option[A]] に変換できます。

  • a.map(_.sequence.map(_.join)).joinを1つずつ説明すると

  • まず a.map(_.sequence) で、真ん中の OptionFuture が入れ替わり Future[Future[Option[Option[Int]]]] になります。

  • また、 M[M[A]] という型があった場合に、もしMMonad ならば(正確にはBindならば) join を呼ぶだけで M[M[A]]M[A] に変換できます。

  • FutureOptionMonad なので join が使えます。

  • a.map(_.sequence.map(_.join))Future[Future[Option[Int]]] と、内側の2重の Option を潰したということです。

  • 最後のjoinで、外側の2重のFutureを潰して完成です。

  • ちなみに、上記では説明の都合上個別に呼び出しましたが a.map(_.sequence.map(_.join)).joina.flatMap(_.sequence.map(_.join)) とも書けます

Scalaz便利ですね!

libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.1.3"
Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scalaz._, syntax.traverse._, std.scalaFuture._, std.option._, syntax.bind._
import scalaz._
import syntax.traverse._
import std.scalaFuture._
import std.option._
import syntax.bind._
scala> import scala.concurrent._
import scala.concurrent._
scala> import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.ExecutionContext.Implicits._
scala> val a: Future[Option[Future[Option[Int]]]] = Future(None)
a: scala.concurrent.Future[Option[scala.concurrent.Future[Option[Int]]]] = scala.concurrent.impl.Promise$DefaultPromise@358404f5
scala> a.map(_.sequence.map(_.join)).join
res0: scala.concurrent.Future[Option[Int]] = scala.concurrent.impl.Promise$DefaultPromise@b340942
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment