我正在使用 Scala中的功能编程进行练习,并实现了一个简单的单链接列表。
这是相关的实现部分:
sealed trait List[+T]
case class Cons[+T](t: T, ts: List[T]) extends List[T]
case object Empty extends List[Nothing]
我建立了一个“很大”列表(隐藏的目标是实现尾递归foldRight
):
def mkBigListOfInt(start: Int, end: Int) = (start to end).foldRight(workshop.List[Int]()) {
case (item, acc) => Cons(item, acc)
}
val veryBigList = mkBigListOfInt(1, 1000000)
当我尝试将列表与另一个列表进行比较时(例如使用Scalatest DSL),就会出现问题:
mkBigListOfInt(1, 1000000) shouldBe mkBigListOfInt(1, 1000000)
我得到:
[error] java.lang.StackOverflowError
[error] at scala.runtime.BoxesRunTime.equals(BoxesRunTime.java:123)
[error] at workshop.Cons.equals(list.scala:81)
[error] at workshop.Cons.equals(list.scala:81)
...
(第81行是我定义的Cons
案例类的行)
实现Cons
以允许比较相等的好方法是什么?
由于这是一种练习,因此我可以使其简单且不完整(前提是要权衡利弊),因此“基本”解决方案目前是可以的。
答案 0 :(得分:2)
案例类equals
的默认实现是幼稚的递归。您可以在List
中实现自己的尾部递归版本。这是一个开始:
sealed trait List[+T] {
override def equals(o: Object): boolean = o match {
case ls: List[_] => equalsRec(ls)
case _ => false
}
@tailrec
def equalsRec(ls: List[_]): boolean = ???