2014-10-31 2 views
0

이것은 이전의 question에 대한 후속 조치입니다. 나는 다음과 같은 기능을 가지고 가정 :스칼라에서 둘 중 하나를 사용하여 오류 처리

type Result[A] = Either[String, A] // left is an error message 

def f1(a: A): Result[B] = ... 
def f2(b: B): Result[C] = ... 
def f3(c: C): Result[D] = ... 

def f(a: A): Result[D] = for { 
    b <- f1(a).right 
    c <- f2(b).right 
    d <- f3(c).right 
} yield d; 

또한 내가 오류 메시지에 정보를 추가 할 가정하자.

def f(a: A): Result[D] = for { 
    b <- { val r = f1(a); r.left.map(_ + s"failed with $a"); r.right } 
    c <- { val r = f2(b); r.left.map(_ + s"failed with $a and $b"); r.right } 
    d <- { val r = f3(c); r.left.map(_ + s"failed with $a, $b, and $c"); r.right } 
} yield d; 

코드가 불투명합니다. 코드를 어떻게 개선 할 것을 제안 하시겠습니까?

+5

왜 그냥'F1의 (a) .left.map (_ + s는 "$ a를 실패했습니다") right'? –

+0

감사. 당신 말이 맞아요. – Michael

+0

함수 f1, f2, f3의 오류 메시지에 인수를 추가하지 않는 이유가 있습니까? – lea

답변

1

코드가 반복적으로 보이기 때문에 추한 것처럼 보입니다.

대신 방법을 작성하십시오! 또는 확장 방법. 어쩌면 이들 중 하나 :.

implicit class StringEitherCanAdd[A](private val e: Either[String, A]) extends AnyVal { 
    def info(s: String): Either[String, A] = e.left.map(_ + s) 
    def failed(a: Any*): Either[String, A] = 
    if (a.length == 0) e 
    else if (a.length == 1) e.left.map(_ + s"failed with ${a(0)}") 
    else if (a.length == 2) e.left.map(_ + s"failed with ${a(0)} and ${a(1)}") 
    else e.left.map(_ + s"failed with ${a.init.mkString(", ")}, and ${a.last}") 
} 

이제 당신은

f1(a).info(s"failed with $a").right 
f2(b).failed(a,b).right 
관련 문제