如何定义一个函数来接受所有扩展通用基本类型的类型(Scala,下面的特定代码)?

six_minute_abs

我在下面的代码块中正确定义我的类型时遇到问题。

我正在尝试做的事情:我正在尝试定义一个称为的通用函数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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

定义一个函数来接受特定的列表参数

来自分类Dev

创建一个函数来接受一个二维数组并返回一个显示所有键:值的对象

来自分类Dev

iOS 如何制作一个函数来接受向 NSCoding 确认的参数

来自分类Dev

TypeScript:引用从一个基本类型扩展的不同类型的多个对象

来自分类Dev

创建一个通用方法Print,它将接受所有类型的集合给它

来自分类Dev

具有通用模板化基本类型的STL容器,接受派生类型

来自分类Dev

如何创建一个接受不同参数类型的通用函数

来自分类Dev

如何检查基本类型列表是否至少包含某些子类型的一个实例

来自分类Dev

在接受基本类型的函数中处理派生类型

来自分类Dev

如何让一个函数接受相同类型的函数?

来自分类Dev

如何禁用基本类型的所有隐式转换?

来自分类Dev

强制转换列表类型,以便一个函数可以接受更通用的列表类型

来自分类Dev

基本类型的通用协议

来自分类Dev

如何创建一个接受所有类型的变量(标量,哈希,数组或引用)的子例程

来自分类Dev

如何让函数接受所有类型的数组

来自分类Dev

我想了解为什么要创建一个类型来处理Go中的错误,以及如何确定它应具有的基本类型

来自分类Dev

如何创建一个返回通用协议类型的函数?

来自分类Dev

如何创建一个类似于“ Data.Vector.modify”的函数来接收列表?

来自分类Dev

如何创建自定义类型以始终表示具有一定数量元素的某些基本类型的数组?

来自分类Dev

“ ILoggingBuilder”不包含“ AddNLog”的定义,也没有扩展方法“ AddNLog”接受“ ILoggingBuilder”类型的第一个参数

来自分类Dev

''不包含'Session'的定义并且没有扩展方法'可以找到接受'object'类型的第一个参数

来自分类Dev

Java:如何编写通用的函数来接受实现给定接口的Enum常量?

来自分类Dev

如何编写一个方法来接受任何扩展Throwable的类的集合?

来自分类Dev

通用构造函数接受类型T的类对象,并返回T,这次T是一个List

来自分类Dev

是否可以使一个函数接受具有相同定义的两个不同的求和类型?

来自分类Dev

我如何定义一个类型,该类型代表所有以ArgType作为参数并返回ReturnType的二进制或一元函数?

来自分类Dev

允许基于相同基本类型的所有类型之一

来自分类Dev

在TypeScript中扩展基本类型,错误:“ _ this未定义...”

来自分类Dev

如何扩展接受数组通用元素的类型?

Related 相关文章

  1. 1

    定义一个函数来接受特定的列表参数

  2. 2

    创建一个函数来接受一个二维数组并返回一个显示所有键:值的对象

  3. 3

    iOS 如何制作一个函数来接受向 NSCoding 确认的参数

  4. 4

    TypeScript:引用从一个基本类型扩展的不同类型的多个对象

  5. 5

    创建一个通用方法Print,它将接受所有类型的集合给它

  6. 6

    具有通用模板化基本类型的STL容器,接受派生类型

  7. 7

    如何创建一个接受不同参数类型的通用函数

  8. 8

    如何检查基本类型列表是否至少包含某些子类型的一个实例

  9. 9

    在接受基本类型的函数中处理派生类型

  10. 10

    如何让一个函数接受相同类型的函数?

  11. 11

    如何禁用基本类型的所有隐式转换?

  12. 12

    强制转换列表类型,以便一个函数可以接受更通用的列表类型

  13. 13

    基本类型的通用协议

  14. 14

    如何创建一个接受所有类型的变量(标量,哈希,数组或引用)的子例程

  15. 15

    如何让函数接受所有类型的数组

  16. 16

    我想了解为什么要创建一个类型来处理Go中的错误,以及如何确定它应具有的基本类型

  17. 17

    如何创建一个返回通用协议类型的函数?

  18. 18

    如何创建一个类似于“ Data.Vector.modify”的函数来接收列表?

  19. 19

    如何创建自定义类型以始终表示具有一定数量元素的某些基本类型的数组?

  20. 20

    “ ILoggingBuilder”不包含“ AddNLog”的定义,也没有扩展方法“ AddNLog”接受“ ILoggingBuilder”类型的第一个参数

  21. 21

    ''不包含'Session'的定义并且没有扩展方法'可以找到接受'object'类型的第一个参数

  22. 22

    Java:如何编写通用的函数来接受实现给定接口的Enum常量?

  23. 23

    如何编写一个方法来接受任何扩展Throwable的类的集合?

  24. 24

    通用构造函数接受类型T的类对象,并返回T,这次T是一个List

  25. 25

    是否可以使一个函数接受具有相同定义的两个不同的求和类型?

  26. 26

    我如何定义一个类型,该类型代表所有以ArgType作为参数并返回ReturnType的二进制或一元函数?

  27. 27

    允许基于相同基本类型的所有类型之一

  28. 28

    在TypeScript中扩展基本类型,错误:“ _ this未定义...”

  29. 29

    如何扩展接受数组通用元素的类型?

热门标签

归档