Last active
June 11, 2017 10:37
-
-
Save tksugimoto/cd28ba3bdabc39cf24735f901810319b to your computer and use it in GitHub Desktop.
Scala Either snippet
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
// Either: LeftとRightのどちらかを取りうるもの(OptionはSome(x)とNoneのどちらかを取りうるもの) | |
// 嬉しさ:OptionはSome(x), Noneだったが、EitherはRight(x), Left(y)になり、None相当のときに情報を持てる(エラー情報を持つことが多い) | |
// Scala 2.11 | |
case class User(id: Int) | |
def findUserById(id: Int): Either[String, User] = { | |
id match { | |
case 2 => Left("存在しない") | |
case 5 => Left("バンされた") | |
case _ => Right(User(id)) | |
} | |
} | |
val userEither1: Either[String, User] = findUserById(1) // Right(User(1)) | |
val userEither2: Either[String, User] = findUserById(2) // Left("存在しない") | |
val userEither3: Either[String, User] = findUserById(3) // Right(User(3)) | |
val userEither4: Either[String, User] = findUserById(4) // Right(User(4)) | |
val userEither5: Either[String, User] = findUserById(5) // Left("バンされた") | |
"================================== パターンマッチ ==================================" | |
userEither1 match { | |
case Left(msg: String) => println(msg) | |
case Right(user: User) => println(user) | |
} // User(1) | |
userEither2 match { | |
case Left(msg: String) => println(msg) | |
case Right(user: User) => println(user) | |
} // "存在しない" | |
case class Result(message: String) | |
def user2result(userEither: Either[String, User]): Result = userEither match { | |
case Left(msg: String) => Result(s"[Userは見つからなかった] 理由: ${msg}") | |
case Right(user: User) => Result(s"id: ${user.id}のUserが見つかった") | |
} | |
user2result(userEither3) // Result("id: 3のUserが見つかった") | |
user2result(userEither4) // Result("id: 4のUserが見つかった") | |
user2result(userEither5) // Result([Userは見つからなかった] 理由: バンされた) | |
"================================== Option化 ==================================" | |
// 情報が減るのであまり使われない気がする | |
// .rightでRightをSome側にできる | |
userEither1.right.toOption // Some(User(1)) | |
userEither2.right.toOption // None | |
userEither3.right.toOption // Some(User(3)) | |
userEither4.right.toOption // Some(User(4)) | |
userEither5.right.toOption // None | |
// .leftでLeftをSome側にできる(あまり使われない気がする) | |
userEither1.left.toOption // None | |
userEither2.left.toOption // Some("存在しない") | |
userEither3.left.toOption // None | |
userEither4.left.toOption // None | |
userEither5.left.toOption // Some("バンされた") | |
"================================== map処理 ==================================" | |
// RightのときにUser情報からidを取り出す | |
val rightMappedUser1: Either[String, Int] = userEither1.right.map((user: User) => user.id) // Right(1) | |
val rightMappedUser2: Either[String, Int] = userEither2.right.map((user: User) => user.id) // Left("存在しない") | |
val rightMappedUser3: Either[String, Int] = userEither3.right.map((user: User) => user.id) // Right(3) | |
// Leftのときにエラーメッセージの長さを先頭に追加 | |
val leftMappedUser1: Either[String, User] = userEither1.left.map((msg: String) => s"${msg.length}: ${msg}") // Right(1) | |
val leftMappedUser2: Either[String, User] = userEither2.left.map((msg: String) => s"${msg.length}: ${msg}") // Left("5: 存在しない") | |
val leftMappedUser3: Either[String, User] = userEither3.left.map((msg: String) => s"${msg.length}: ${msg}") // Right(3) | |
// 両方 | |
val leftRightMappedUser1: Either[String, Int] = userEither1 | |
.left.map((msg: String) => s"${msg.length}: ${msg}") | |
.right.map((user: User) => user.id) // Right(1) | |
val leftRightMappedUser2: Either[String, Int] = userEither2 | |
.left.map((msg: String) => s"${msg.length}: ${msg}") | |
.right.map((user: User) => user.id) // Left("5: 存在しない") | |
val leftRightMappedUser3: Either[String, Int] = userEither3 | |
.left.map((msg: String) => s"${msg.length}: ${msg}") | |
.right.map((user: User) => user.id) // Right(3) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment