scala - 协方差如何在简单函数中发挥作用

标签 scala covariance

我正在尝试简单地利用 Scala 协方差原理。我希望下面的 max 和 sum 方法能够与 IntDouble 或任何其他 NumericList 一起使用类型。 下面的代码返回以下错误:

type mismatch;
found: Int(2)
required: T1 
in max(List(2,3,4))
object Main extends App {

  class utils[+T1 <: Ordered[T1], +T2 <: Numeric[T1]] {

    def max(input_list: List[T1]): T1 = {

      def inside_max(i: Int, current_max: T1): T1 = {
        if (i >= input_list.size) current_max
        if (input_list(i) < current_max) {
          inside_max(i + 1, current_max: T1)
        } else {
          inside_max(i + 1, input_list(i))
        }
      }

      inside_max(0, input_list(0))
    }

    def sum(input_list: List[T2]): T2 = {

      def inside_sum(i: Int, current_sum: T2): T2 = {
        if (i >= input_list.size) current_sum
        val new_sum: T2 = implicitly[Numeric[T2]](Numeric[T2]).plus(current_sum, input_list(i))
        inside_sum(i + 1, new_sum)
      }

      inside_sum(1, input_list(0))
    }

    max(List(2,3,4))

  }

}

最佳答案

您将方差子类型类型类混合在一起,这些是不同的概念。

在这种情况下,您实际上只想使用Numeric typeclass

object Utils {
  def max[T : Ordering](list: List[T]): Option[T] = {
    import Ordering.Implicits._

    @annotation.tailrec
    def loop(remaining: List[T], currentMax: T): T =
      remaining match {
        case Nil =>
          currentMax

        case t :: tail =>
          val newMax =
            if (t >= currentMax)
              t
            else
              currentMax

          loop(
            remaining = tail,
            newMax
          )
      }

    list match {
      case Nil => None
      case t :: tail => Some(loop(remaining = tail, currentMax = t))
    }
  }

  def sum[T : Numeric](list: List[T]): T = {
    import Numeric.Implicits._

    def loop(remaining: List[T], acc: T): T =
      remaining match {
        case Nil =>
          acc

        case t :: tail =>
          loop(
            remaining = tail,
            acc + t
          )
      }

    loop(remaining = list, acc = Numeric[T].zero)
  }
}

你可以这样使用:

Utils.sum(List(1, 2, 3))
// res: Int = 6

Utils.sum(List.empty[Int])
// res: Int = 0

Utils.max(List.empty[Int])
// res: Option[Int] = None

Utils.max(List(1, 2, 3))
// res: Option[Int] = Some(3)

关于scala - 协方差如何在简单函数中发挥作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58137645/

相关文章:

multithreading - Iterator.continually : special proccessing for the first element

macos - Jupyter-Scala 笔记本不断重新启动并出现 NullPointerException

scala - BodyParser 根据请求体返回结果

Java 类型转换问题

scala - 按类型过滤 Scala 列表

r - 在 R 中计算 T2 统计量

scala - Scala 中的类型提取

c# - 将 B 添加到 List<A<object>>,其中 B 使用值类型实现 A

c# - 将 List<bool> 转换为 List<object>

multithreading - 在 Scala 中,Await、Thread.sleep 和 for comprehensions 有什么区别?