我想弄清楚为什么下面的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]
,因此,由于参数类型不匹配,我认为编译器应该抛出错误。但是代码编译得很好。
你能帮我理解代码编写的原因吗?
答案 0 :(得分:2)
在tester[A,B]
方法中,您实际上正在调用map[A, List[B]]
。
如果您使用不同的类型参数编写测试器方法,那么代码更容易理解,然后调用map
,A = C
和B = List[D]
。
def tester[C, D](as: List[C])(f1: C => List[D]): List[List[D]] = {
map[C, List[D]](as)(f1)
}
答案 1 :(得分:1)
我认为您的误解来自于您假设A
和B
类型对于map
和tester
都是通用的,而实际上它们实际上是本地定义。出于此示例的目的,我们将B
的{{1}}重命名为tester
。这意味着C
的{{1}}实际上将是B
。