【问题标题】:Difference b/w Method[Int]() vs Method() in scala?scala中的b / w Method [Int]()与Method()的区别?
【发布时间】:2021-04-03 17:36:02
【问题描述】:

在scala中看到map的方法签名后

def map[A, B](l: List[A])(f: A => B): List[B] = ???

我对上面 [A, B] 的外行理解是,它们表明我们将在定义的方法中专门使用泛型 A 和 B 类型。

现在我继续实现一种方法,使用类似的编码模式从两个列表中连续添加值(基本上是 zipWith)。

def addCorresponding[Int](l1: List[Int],
                        l2: List[Int]): List[Int] =
  (l1, l2) match {
      case (_, Nil) => Nil
      case (Nil, _) => Nil
      case (x::xs, y::ys) => {
          List((x + y)) ++ addCorresponding(xs, ys)
      }
}

但在最后一个匹配项中添加元素时出现此错误: type mismatch found: Int Required: String

从方法签名中删除 [Int] 可修复此错误。

我确信我对泛型类型以及何时将它们添加到方法签名中的理解存在漏洞。如果有人能指导我并解释为什么带有 [Int] 的 addCorresponding 方法会出错但没有它也能正常工作,我将不胜感激?

【问题讨论】:

  • 类型参数基本上就是一个参数。就像当你做def plusFive(x: Int): Int = x + 5时,x是什么?任何东西,任何东西都传递给函数。它不是1,也不是0,甚至不是53,它只是一个参数。所以在第一个例子中AB 是类型的参数,这意味着它们现在不是任何正确的类型,它们将在调用时由编译器填充。在您的第二个示例中,您希望两个列表都是 Int 类型,因为您想对元素求和,这是您只能使用 Ints 执行的操作,因此不需要添加类型参数。
  • 另请注意,当您执行 [Int] 时,您正在创建一个名为 Int 的类型参数,它会隐藏类型 Int,这就是为什么当您执行添加。
  • 啊,现在说得通了。谢谢你的回答。
  • 有一个非常相似的问题:stackoverflow.com/q/65322171/2359227
  • 顺便说一句,你为什么不使用zip?它完全符合您的要求。 scastie.scala-lang.org/yYCapPvmSgWWE467QRh4ZQ

标签: scala functional-programming


【解决方案1】:

泛型方法(采用类型参数)将是

def addCorresponding[A](l1: List[A], l2: List[A]): List[A]

或者,如果列表可以包含不同类型的元素

def addCorresponding[A, B, C](l1: List[A], l2: List[B]): List[C]

如果你实现了一个适用于具体类型Int的方法,那么你的方法就不再是通用的了:

def addCorresponding(l1: List[Int], l2: List[Int]): List[Int]

换句话说,您在此处将具体类型Int 应用于List[_],而不是抽象类型参数。如果你写

def addCorresponding[Int](l1: List[Int], l2: List[Int]): List[Int]

然后你“影子”具体类型Int 与抽象类型参数Int 恰好具有相同的名称;但从技术上讲,您正在编写通用方法

def addCorresponding[XXX](l1: List[XXX], l2: List[XXX]): List[XXX]

如果你想保持你的方法通用但对A类型的元素执行某些操作,你可能需要一个类型类,例如Numeric来算术添加元素

def addCorresponding[A](l1: List[A],
                        l2: List[A])(implicit num: Numeric[A]): List[A] =
  (l1, l2) match {
    case (_, Nil) => Nil
    case (Nil, _) => Nil
    case (x::xs, y::ys) =>
      List((num.plus(x, y))) ++ addCorresponding(xs, ys)
  }

【讨论】:

  • 感谢您的详细回答和通用实现。
猜你喜欢
  • 2013-11-15
  • 2014-09-14
  • 2017-02-28
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-29
相关资源
最近更新 更多