Either
エフェクトは
Option
エフェクトに似ているが、計算が止まった理由を含める能力を追加している。
import org.atnos.eff._, all._, syntax.all._
/**
* スタックの宣言
*/
type S = Fx.fx1[Either[String, *]]
// このスタックを計算
val map: Map[String, Int] =
Map("key1" -> 10, "key2" -> 20)
// マップから2つのキーを取りだし、それらに対応する値を結合する
def addKeys(key1: String, key2: String): Eff[S, Int] = for {
a <- optionEither(map.get(key1), s"'$key1' not found")
b <- optionEither(map.get(key2), s"'$key2' not found")
} yield a + b
(addKeys("key1", "key2").runEither.run, addKeys("key1", "missing").runEither.run)
> (Right(30),Left('missing' not found))
catchLeft
メソッドは、エラーを傍受して場合により復旧させるために使うことができる。
case class TooBig(value: Int)
type E = Fx.fx1[Either[TooBig, *]]
val i = 7
val value: Eff[E, Int] =
if (i > 5) left[E, TooBig, Int](TooBig(i))
else right[E, TooBig, Int](i)
val action: Eff[E, Int] = catchLeft[E, TooBig, Int](value) { case TooBig(k) =>
if (k < 10) right[E, TooBig, Int](k)
else left[E, TooBig, Int](TooBig(k))
}
action.runEither.run ==== Right(7)
備考: left
と
right
の型注釈は、スコープ内宣言を追加することで避けられる。詳しくは
Implicits
セクションで学べる。