2016-06-20 4 views
2

이 내 이전 question의 후속이다 :

나는이 같은 함수 리팩토링하고 가정하자 :

def check(ox: Option[Int]): Unit = ox match { 
    case None => throw new Exception("X is missing") 
    case Some(x) if x < 0 => throw new Exception("X is negative") 
    case _ =>() 
} 

내가 쓰고을 새 순수 함수 doCheckUnit 또는 예외를 반환합니다.

case class MissingX() extends Exception("X is missing") 
case class NegativeX(x: Int) extends Exception(s"$x is negative") 

import scalaz._, Scalaz._ 

type Result[A] = Excepiton \/ A 

def doCheck(ox:Option[Int]): Result[Unit] = for { 
    x <- ox toRightDisjunction MissingX() 
    _ <- (x >= 0) either(()) or NegativeX(x) 
} yield() 

다음이 의미가 있는가 check

def check(ox:Option[Int]): Unit = doCheck(ox) match { 
    case -\/(e) => throw e 
    case _ =>() 
} 

에서 호출? 그런 식으로 doCheck을 구현하는 것이 더 낫겠습니까?

def doCheck(ox:Option[Int]): Result[Int] = for { 
    x1 <- ox toRightDisjunction MissingX() 
    x2 <- (x1 >= 0) either(x1) or NegativeX(x1) 
} yield x2 

어떻게 cats 그것을 구현하는 방법?

+0

왜 당신은 여전히'check'에서 예외를 발생합니까? –

+0

@PeterNeyens'check' 밖에서 모든 코드를 변경하고 싶지는 않습니다. – Michael

답변

2

당신은 cats에서 거의 동일 할 것이고, 고양이 자체는 scalaz에서 either() or() 같은 Boolean => Xor[A, B] 구문을 갖지 않을 것입니다.

import cats.data.Xor 
import cats.implicits._ 

def doCheck(ox: Option[Int]): Xor[Exception, Unit] = 
    ox.toRightXor(MissingX()).flatMap(x => if(x > 0)().right else NegativeX(x).left) 

당신은 고양이 유사한 구문 헬퍼를 제공 mouse, 사용할 수 있습니다

import com.github.benhutchison.mouse.boolean._ 

ox.toRightXor(MissingX()).flatMap(x => (x > 0).toXor(NegativeX(x),())) 

Xor이 같은 일을 할 수있는 방법 ensure을 가지고,하지만 당신이 요소에 대한 액세스를 제공하지 않습니다 술어가 보유되지 않은 경우 당신이 NegativeX에 대한 x이 필요하지 않은 경우, 당신이 쓴 수 :

ox.toRightXOr(MissingX()).ensure(Negative())(_ > 0).void 
+0

감사합니다. 'scalaz' 버전이 더 멋지게 보입니다 ... – Michael