2017-03-07 1 views
1

나는 scalazs disjunction을 활용하는 자체 오류 유형으로 예외를 래핑하고 싶습니다.커링으로 하한 - 간단하게 할 수 있습니까?

다음 코드는

trait Result 
trait Error extends Result 
object MyError extends Error 
object OK extends Result 

val r: Error \/ OK.type = tryCatchIn(_ => MyError /*:Error*/) { 
    val result: Error \/ OK.type = ??? 
    result 
} 

내가 카레 구문을 유지하고 싶습니다 컴파일해야하며, 명시 적으로 MyError를 입력 좋아하지 않는다. 나의 현재 솔루션은 두 가지 내 의도 훨씬 더를 반영

def tryCatchIn2[L, R](exceptionTransformer: Throwable => L, `finally`: => Unit =() =>()): CatchFinally[L] = { 
    new CatchFinally(exceptionTransformer, `finally`) 
    } 

    class CatchFinally[L](val exceptionTransformer: Throwable => L, `finally`: => Unit =() =>()) { 
    def apply[L2 >: L, R](block: => L2 \/ R): L2 \/ R = try { 
     block 
    } catch { 
     case NonFatal(e) => -\/(exceptionTransformer(e)) 
    } finally { 
     `finally` 
    } 
    } 

내 초기, 카레 접근 ​​방식을 사용

,하지만 난 이 작동하지 수 있습니다

def tryCatchIn[L, R, L2 >: L](exceptionContainer: Throwable => L, `finally`: => Unit =() =>()) 
           (block: => L2 \/ R): L2 \/ R = { 
    try { 
     block 
    } catch { 
     case NonFatal(e) => -\/(exceptionContainer(e)) 
    } finally { 
     `finally` 
    } 
    } 

가 명확 솔루션입니다 가능한? 어쩌면

답변

0

나는 당신의 의도의 일부를 잃었지만이 코드는 훨씬 간단하지 않을 것이다 :

def tryCatchIn[L, R](exceptionContainer: Throwable => L, `finally`: => Unit =()) 
         (block: => R): L \/ R = { 

    try { 
     \/-(block) 
    } catch { 
     case NonFatal(e) => -\/(exceptionContainer(e)) 
    } finally { 
     `finally` 
    } 
} 

일예 R 만 반환하고 () =>() 대신에 ()이되며 형식 위조는 필요하지 않습니다. 당신은 해고 심지어하고자하는 경우 마지막으로 당신이 할 수있는 차단 : 경우

def catchMe[L,R](exceptionContainer: Throwable => L)(block: => R) : L \/ R = { 
    Try {block}.toDisjunction.leftMap(exceptionContainer) 
} 

당신이 당신의 솔루션이 기능 서명을해야합니다 작업 할 : \/\/[+A,+B]으로 정의된다

def tryCatchIn[L, R, L2 >: L](exceptionContainer: Throwable => L2, `finally`: => Unit =() =>()) 
         (block: => L \/ R): L2 \/ R 

때문이다. L2 :> L 트릭을 사용하는 것이 해결책이지만 정확한 리턴 유형을 사용해야합니다.

+0

형식을 올바르게 유추하지 않습니다. 위의 예제 코드를 컴파일 해보십시오. –

+0

흠. 비참하게도 유형을 추론하는 데 실패한 IntelliJ 워크 시트에서도 잘 작동합니다. (1/0) val result2 = catchMe (e => "예외가 발생했습니다 : $ {e.getMessage}", "예외가 발생했습니다 : $ {e.getMessage}") (1/0) ''' 둘 다 문자열 \/Int으로 유추됩니다. – Markus

+0

제 3 행에서'trait Result','object MyError' 등으로 예제 코드를 시도 했습니까? –

관련 문제