Я играю с упражнениями Функциональное программирование в 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 - строка, в которой я определил * case-класс Cons
)
Что было бы хорошим способом реализовать Cons
, чтобы позволить сравнение равенства?
Поскольку это упражнение, для меня нормально держать его простым и неполным (при условии, что найдены компромиссы), поэтому «базовое» решение пока подойдет.