1

の左側に労働組合を作成すると、タイプR1 => Either[L2, R2]の機能にEither[L1, R1]の値をバインドして宣言することができEither[L1 | L2, R2]ので、個々の関数の値を取得し、潜在的に自分のエラーや消費者を返す方法はありますこれらの関数のモナドパイプラインは、可能なすべてのエラーを型付きのない完全な方法できれいに処理できますか?私は徹底的なエラー処理を行うことができないんだけど、その戻り値の型でどちらのタイプ

編集

ここでは一例です...

sealed trait IncrementError 
case object MaximumValueReached extends IncrementError 

def increment(n: Int): Either[IncrementError, Int] = n match { 
    case Integer.MAX_VALUE => Left(MaximumValueReached) 
    case n => Right(n + 1) 
} 

sealed trait DecrementError 
case object MinimumValueReached extends DecrementError 

def decrement(n: Int): Either[DecrementError, Int] = n match { 
    case Integer.MIN_VALUE => Left(MinimumValueReached) 
    case n => Right(n - 1) 
} 

for { 
    n <- increment(0).right 
    n <- decrement(n).right 
} yield n // scala.util.Either[Object, Int] = Right(0) 

。標準的なScala Eitherを使用してこれを行う方法がある場合、またはこの動作をサポートするscalazのようなライブラリに何かが存在するかどうか不思議です。私は

val n = for { 
    n <- increment(0).right 
    n <- decrement(n).right 
} yield n // scala.util.Either[IncrementError | DecrementError, Int] 

match n { 
    case Left(MaximumValueReached) => println("Maximum value reached!") 
    case Left(MinimumValueReached) => println("Minimum value reached!") 
    case Right(_) => println("Success!") 
} 
+0

標準では 'Either'は/ flatMapを' LeftProjection'または 'RightProjection'に変換することでバイアスされた方法でのみマップすることができます。あなたの提案には好都合ではありませんが、実際にはかなり実行可能です:) –

+0

'L1 | L2?右投影を使うことができますが、結果の型は '[LC、RC]'になります。 'LC'は' L1'と 'L2'の最も近い共通の祖先です。それはあなたが期待するものですか? –

+0

@AlexanderArendarこの動作をサポートするScalazまたはCatsには何かがありますか? –

答えて

0

は、私は次のだろう...このようなエラーを処理できるようにしたいと思います。正直なところ

/** 
    * Created by alex on 10/3/16. 
    */ 
object Temp{ 
    sealed trait IncrementError 
    case object MaximumValueReached extends IncrementError 
    sealed trait DecrementError 
    case object MinimumValueReached extends DecrementError 

    type MyResult = Either[Either[IncrementError, DecrementError], Int] 

    def increment(n: Int): MyResult = n match { 
    case Integer.MAX_VALUE => Left(Left(MaximumValueReached)) 
    case n => Right(n + 1) 
    } 

    def decrement(n: Int): MyResult = n match { 
    case Integer.MIN_VALUE => Left(Right(MinimumValueReached)) 
    case n => Right(n - 1) 
    } 

    def main(args:Array[String]) = { 
    val result = for { 
     k <- increment(0).right 
     n <- decrement(k).right 
    } yield n 

    result match { 
     case Left(Left(MaximumValueReached)) => println("Maximum value reached!") 
     case Left(Right(MinimumValueReached)) => println("Minimum value reached!") 
     case Right(_) => println("Success!") 
    } 
    } 
} 

私はそれを好きではないが、それはケースのために働く場合は、あなたドン何らかの理由でIncrementErrorDecrementErrorをいくつかの祖先の特性から継承したいと思っていません。

関連する問題