我在业余时间尝试刷新一点Scala。我的问题是,为什么我必须注释' size'在这里使用多态类型A
。当我计算树的大小时,我对这些信息不感兴趣。尽管如此,Scala编译器强迫我这样写:
def size[A](t: Tree[A]): Int = {
t match {
case Leaf => 1
case Branch(l,r) => 1 + size(l) + size(r)
}
}
而不是:
def size(t: Tree): Int = {
t match {
case Leaf => 1
case Branch(l,r) => 1 + size(l) + size(r)
}
}
此功能的上下文:
package fpinscala.datastructures
sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
object Tree {
def size[A](t: Tree[A]): Int = {
t match {
case Leaf => 1
case Branch(l,r) => 1 + size(l) + size(r)
}
}
}
答案 0 :(得分:4)
首先注意你的功能有问题:
case Leaf => 1
与Leaf
伴侣对象相等而不是案例类匹配;你应该写一下:
case Leaf(_) => 1
然后您可以使用通配符存在类型来避免类型:
def size(t: Tree[_]): Int = {
t match {
case Leaf(_) => 1
case Branch(l,r) => 1 + size(l) + size(r)
}
}
另请注意,您的尺寸函数也会计算分支数量,我认为您更有可能只想数叶子;在这种情况下,将其更改为:
case Branch(l,r) => size(l) + size(r)
计算分支机构:
size(Branch(Branch(Leaf(1),Leaf(2)),Leaf(3))) = 5
计算叶子:
Branch(Branch(Leaf(1),Leaf(2)),Leaf(3)) = 3
答案 1 :(得分:0)
关于你的评论,你有这个:
object Tree {
def size[A](t: Tree[A]): Int = { //you would want to avoid specifying the first [A]
t match {
case Leaf => 1
case Branch(l,r) => 1 + size(l) + size(r)
}
}
}
请注意,伴随对象不涉及泛型类型,因此必须在其方法上指定,否则编译器将搜索A
class(在解析size
的参数时),显然不存在。
您想告诉编译器: A是一种泛型类型,而不是特定类型!
所以它不是一个样板,它是编译器需要的东西,它看起来很合乎逻辑。