我在下面的代码块中正确定义我的类型时遇到问题。
我正在尝试做的事情:我正在尝试定义一个称为的通用函数processMyFuncResult
,该函数接受另一个函数(工作函数)的结果,在计算成功的情况下要调用的函数以及在失败时要调用的函数。我的意图是拥有许多不同类型的辅助函数,其结果在内容上是可变的,但应该扩展其特性MyFuncResult[T]
。
问题:
在下面的代码中,我正在生成一个编译错误,经过很多努力之后,似乎无法找到有效的解决方案,在该解决方案中,我可以将上下文的特定子类型传递给OnSuccess和OnFailure函数。
我尝试将新类型的参数引入结果处理函数并弄乱边界和方差,前者具有将相同问题推入主体的processMyFuncResult
作用,后者似乎没有作用,但是我用尽我的调整无济于事。
编译错误:
Error:(37, 41) type mismatch;
found : (Int, WorkerContext) => Unit
required: (?, MyFuncContext) => Unit
processMyFuncResult(exampleComputation, printWorkerSuccess, printWorkerFailure)
Error:(37, 61) type mismatch;
found : (CouldntDoitError, WorkerContext) => Unit
required: (MyError, MyFuncContext) => Unit
processMyFuncResult(exampleComputation, printWorkerSuccess, printWorkerFailure)
码:
// ErrorTypes
trait MyError
case class CouldntDoitError(msg: String) extends MyError
// Context for passing more information to post-processing function
trait MyFuncContext
case class WorkerContext(passedArg: Int) extends MyFuncContext
// Traits / Types for Worker func results - all workers should return this kind of result
trait WorkerFuncResult[T] {
def result: Either[MyError, T]
def context: MyFuncContext
}
case class WorkerResult(result: Either[MyError, Int], context: MyFuncContext) extends WorkerFuncResult[Int]
// Processing function which does the interesting work and returns a WorkerFuncResult
// There are many of these which have specific types which they return (e.g. WorkerResult)
def workerFunc(a: Int): WorkerResult = {
val compRes = for {
res1 <- if (a < 10) Left(CouldntDoitError("Less than 10 ")) else Right(a * 2)
res2 <- if (a < 30) Left(CouldntDoitError("almost made it but didn't")) else Right(res1 * 100)
} yield res2
WorkerResult(compRes, WorkerContext(a))
}
// Post-processing function - takes a result and invokes an on success function or on failure function
// On the appropriate result or error
def processMyFuncResult[T](computationResult: WorkerFuncResult[T],
onSuccess: (T, MyFuncContext) => Unit,
onFailure: (MyError, MyFuncContext) => Unit) =
computationResult.result match {
case Right(v) => onSuccess(v, computationResult.context)
case Left(e) => onFailure(e, computationResult.context)
}
// Example On Success function
def printWorkerSuccess(res: Int, c: WorkerContext): Unit = println(s"Successful result was $res. " +
s"Original arg was ${c.passedArg}")
// Example on failure function
def printWorkerFailure(res: CouldntDoitError, c: WorkerContext): Unit = println(s"Couldn't do it msg: ${res.msg}. " +
s"Original arg was ${c.passedArg}")
// Running the computation and processing the result
val exampleComputation = workerFunc(3)
processMyFuncResult(exampleComputation, printWorkerSuccess, printWorkerFailure)
这里很多-感谢您的帮助。
问题是,如果您的价值为
trait WorkerFuncResult[T] {
def result: Either[MyError, T]
def context: MyFuncContext
}
和一个函数CouldntDoitError => Something
,它不能处理结果中的所有错误-它可能包含不是的错误CouldntDoitError
。
如果要能够在类型中表达要处理的内容,则需要优化类型。在您的情况下,您将需要两个额外的类型参数:
trait WorkerFuncResult[T, E <: MyError, C <: MyFuncContext] {
def result: Either[E, T]
def context: C
}
case class WorkerResult[E <: MyError](result: Either[E, Int], context: WorkerContext) extends WorkerFuncResult[Int, E, WorkerContext]
// Processing function which does the interesting work and returns a WorkerFuncResult
// There are many of these which have specific types which they return (e.g. WorkerResult)
def workerFunc(a: Int): WorkerResult[CouldntDoitError] = {
val compRes = for {
res1 <-
if (a < 10) Left(CouldntDoitError("Less than 10 "))
else Right(a * 2)
res2 <-
if (a < 30) Left(CouldntDoitError("almost made it but didn't"))
else Right(res1 * 100)
} yield res2
WorkerResult(compRes, WorkerContext(a))
}
// Post-processing function - takes a result and invokes an on success function or on failure function
// On the appropriate result or error
def processMyFuncResult[T, E <: MyError, C <: MyFuncContext](
computationResult: WorkerFuncResult[T, E, C],
onSuccess: (T, C) => Unit,
onFailure: (E, C) => Unit
) =
computationResult.result match {
case Right(v) => onSuccess(v, computationResult.context)
case Left(e) => onFailure(e, computationResult.context)
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句