【问题标题】:Scala function accepts different typeScala函数接受不同的类型
【发布时间】:2017-09-10 00:51:09
【问题描述】:

我想弄清楚为什么下面的 Scala 代码会编译?

trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

def map[A, B](as: List[A])(f: A => B): List[B] = as match {
  case Nil         => Nil
  case Cons(x, xs) => Cons(f(x), map(xs)(f))
}

def tester[A, B](as: List[A])(f1: A => List[B]) = map(as)(f1)

根据我的理解,tester 不应该编译,因为map 的定义说它接受两个参数:一个列表列表一个类型为A => B 的函数。

但是,在tester 函数中,我有函数f1,它的类型是A => List[B],所以,作为参数不匹配的类型,我认为编译器应该抛出错误。但是代码编译正常。

你能帮我理解为什么代码在这里编译吗?

【问题讨论】:

  • .map 应该声明一个类型参数A,否则这会在特征级别隐藏类型参数A(无论如何在这种情况下都没用)
  • @cchantep map 在特征之外。

标签: scala


【解决方案1】:

tester[A,B] 方法中,您实际上是在调用map[A, List[B]]

如果你用不同的类型参数编写测试器方法,那么代码可能更容易理解,然后在mapA = CB = List[D]的调用中。

def tester[C, D](as: List[C])(f1: C => List[D]): List[List[D]] = {
  map[C, List[D]](as)(f1)
}

【讨论】:

  • 感谢您的回复。我实际上忘记了 Scala 编译器从传递的参数推断参数的类型。我怎么还是不明白为什么在测试方法中地图实际上是 map[A,List[B]] ? as 的类型是 List[A] , f1 的类型是 A=>List[B] 。那么地图不应该是 map[List[A], A=>List[B] ] 吗?
  • @Somenath 编译器推断 map 的类型参数,使得调用中的参数 asf 是兼容的。由于f1:A => List[B]map 必须是map[A, List[B]]
【解决方案2】:

我认为您的误解源于您假设AB 类型对于maptester 都是通用的,而它们实际上是本地定义的。出于本示例的目的,我们将testerB 重命名为C。这意味着mapB 实际上是List[C]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    相关资源
    最近更新 更多