我想在利用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 :(得分:0)
也许我错过了你的一些意图,但这段代码不会更简单:
UPDATE ACCOUNTS SET STATUSID = 5 WHERE ACCOUNTNAME = '#ACCOUNTNAME' AND STATUSID = 4
E.g。只返回def tryCatchIn[L, R](exceptionContainer: Throwable => L, `finally`: => Unit = ())
(block: => R): L \/ R = {
try {
\/-(block)
} catch {
case NonFatal(e) => -\/(exceptionContainer(e))
} finally {
`finally`
}
}
,最后只是R
而不是()
,不需要类型欺骗。如果你甚至愿意解雇finally块,你可以这样做:
() => ()
如果您希望解决方案正常工作,您将需要此功能签名:
def catchMe[L,R](exceptionContainer: Throwable => L)(block: => R) : L \/ R = {
Try {block}.toDisjunction.leftMap(exceptionContainer)
}
因为def tryCatchIn[L, R, L2 >: L](exceptionContainer: Throwable => L2, `finally`: => Unit = () => ())
(block: => L \/ R): L2 \/ R
被定义为\/
。使用\/[+A,+B]
技巧是解决方案,但您还需要使用正确的返回类型。