diff --git a/src/main/scala/datastructures/List.scala b/src/main/scala/datastructures/List.scala index 97e497d1f9c561aede0b831aaf9e13deb76e80d0..e64c3fe5aefcb39b2be93aac3ffb6cbd46b4d6e7 100644 --- a/src/main/scala/datastructures/List.scala +++ b/src/main/scala/datastructures/List.scala @@ -1,21 +1,33 @@ package datastructures -sealed trait List[+A]: - def head = this match +enum List[+A]: + case Nil + case Cons(_head: A, _tail: List[A]) + + def head: A = this match case Nil => sys.error("head of empty list") case Cons(a, _) => a + /** removes the first element of a list and returns the rest */ def tail: List[A] = ??? + /** returns all but the last element of a list */ def init: List[A] = ??? + /** replaces the first element of a list */ def setHead[AA >: A](head: AA): List[AA] = ??? + /** recurses through the list, combining elements with the given function + * Uncomment the annotation to enable checking for tail-recursiveness */ + //@annotation.tailrec def foldLeft[B](z: B)(f: (B, A) => B): B = ??? -case object Nil extends List[Nothing] -case class Cons[+A](elem: A, rest: List[A]) extends List[A] object List: + /** construct a list by passing elements + * + * Remember: `apply` makes the object behave like a function, + * you can call it as `List(elem1, elem2,...)` + **/ def apply[A](as: A*): List[A] = if as.isEmpty then Nil else Cons(as.head, apply(as.tail: _*)) diff --git a/src/test/scala/datastructures/ListSpec.scala b/src/test/scala/datastructures/ListSpec.scala index 30ca84a5f29e0c3f8e8439992a076c18e7e01409..f067becc0ff6373c7da0bf756a0d78030883dd4f 100644 --- a/src/test/scala/datastructures/ListSpec.scala +++ b/src/test/scala/datastructures/ListSpec.scala @@ -12,13 +12,13 @@ class ListSpec extends AnyFlatSpec with Matchers with AppendedClues with Pending "A list" should "have a tail function that removes the first element" in { numbers.tail shouldBe List(2, 3, 4, 5) - single.tail shouldBe Nil + single.tail shouldBe List.Nil a[RuntimeException] should be thrownBy List().tail } it should "have a init function that removes the last element" in { numbers.init shouldBe List(1, 2, 3, 4) - single.init shouldBe Nil + single.init shouldBe List.Nil a[RuntimeException] should be thrownBy List().init } @@ -31,4 +31,4 @@ class ListSpec extends AnyFlatSpec with Matchers with AppendedClues with Pending strings.foldLeft("X")(_ + _) should not be "Xcba" withClue ", this looks like a right fold with flipped args" strings.foldLeft("X")(_ + _) shouldBe "Xabc" } -} \ No newline at end of file +}