Created
March 20, 2017 17:29
-
-
Save martinloverse/d7ddd5ddc2c5bce32a60e0b34d02d87a to your computer and use it in GitHub Desktop.
Scala For Comprehension Samples
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.concurrent.Future | |
val maybeName: Option[String] = Some("martin.lover") | |
val maybeAge: Option[Int] = Some(33) | |
case class Person(name:String, age:Int) | |
val person: Option[Person] = | |
for { | |
name <- maybeName | |
age <- maybeAge | |
} yield Person(name, age) | |
// このように展開される。 | |
val person2: Option[Person] = | |
maybeName flatMap { name => | |
maybeAge map { age => | |
Person(name, age) | |
} | |
} | |
val maybeAddr: Option[String] | |
// こういうコードを書きがち。パターンマッチやflatMapのネストを発見したらforで書き換えるプルリクチャンス! | |
maybeName match { | |
case Some(name) => maybeAge match { | |
case Some(age) => maybeAddr match { | |
case Some(addr) => Person(name, age) | |
case None => None | |
} | |
case None => None | |
} | |
case None => None | |
} | |
(maybeName, maybeAge, maybeAddr) match { | |
case (Some(name), Some(age), Some(addr)) => Some(Person(name, age)) | |
case _ => None | |
} | |
// map, flatMapを実装している型で上記のような表現が使える。 | |
// コップ本23章 for式の再説に詳しい。 | |
// 「文脈付きの値」flatMap3兄弟 | |
// Option[A] あるかもしれないし、ないかもしれない値 | |
val request: Map[String, String] = ??? | |
case class Device(ua: String, ip: String, idfa: Option[String]) | |
// ua, ipがなければDeviceはNone. idfaはないかもしれないのでなくてもOK | |
for { | |
ua <- request.get("ua") | |
ip <- request.get("ip") | |
idfa = request.get("idfa") | |
} yield Device(ua, ip, idfa) | |
// Future[A] 未来に取得できるかもしれないし、できないかもしれない値 | |
case class Artist(name: String) | |
case class Song(name: String) | |
def searchArtist(name: String): Future[Artist] = ??? | |
def searchSongs(artist: Artist): Future[Seq[Song]] = ??? | |
import scala.concurrent.ExecutionContext.Implicits.global | |
val maybeSongs:Future[Seq[Song]] = | |
for { | |
// flatMapで展開されるということは、この書き方では順次実行になるので注意! | |
artist <- searchArtist("martin.lover") | |
songs <- searchSongs(artist) | |
} yield songs | |
// Either[A] 右(成功)かもしれないし、左(失敗)かもしれない値 | |
def validateName(name: String): Either[String, String] | |
def validateAge(age: Int): Either[String, Int] | |
// Scala 2.12でEither が Right-Biasになった。no more `.right`! | |
val validPerson = | |
for { | |
name <- maybeName toRight "Name is Required" | |
age <- maybeAge toRight "Age is Required" | |
_ <- validateName(name) | |
_ <- validateAge(age) | |
} yield Person(name, age) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment