MyList - step 3
Add method
- Add the
addmethod - Add the
+method - Create a companion object
Exercise 1
trait MyList[A]:
...
def add(element: A): MyList[A]
- Give the MyList trait an
addmethod - Implement it in Cons and Empty
- And test it in main with:
Empty().add(1).add(2).add(3)
Exercise 2
trait MyList[A]:
...
def +(element: A): MyList[A]
- Implement + operator as alias for add method
- And test it in main with:
Empty() + 1 + 2 + 3
Exercise 3
object MyList:
def apply[A](elements: A*): MyList[A]
- Implement the companion object
- And test it in main with:
MyList(1,2,3)
Add method
Empty
override def add(element: A): MyList[A] = Cons(element, this)
Adding an element to Empty means that Empty is not empty anymore and becomes a Cons with the tail Empty (this)
Cons
override def add(element: A): MyList[A] = Cons(element, this)
Adding an element to Cons means adding new head and the tail becomes the current Cons (this)
trait
trait MyList[A]:
...
def add(element: A): MyList[A] = Cons(element, this)
The implementation in Empty and Cons are the same.
So we can move it up to the MyList trait (and remove them from Empty and Cons).
Via inheritance, they are available in Empty and Cons again
main
@main
def main(): Unit =
val myList: MyList[Int] = Empty().add(1).add(2).add(3)
println(myList)
// MyList(3, 2, 1)
The order is reversed now.
Solution 2
trait MyList[A]:
...
def add(element: A): MyList[A] = Cons(element, this)
infix def + (element: A): MyList[A] = add(element)
In Scala + is a valid function name
With the infix modifier we do not have to use the braces in the function call.
@main
def main(): Unit =
val myList: MyList[Int] = Empty() + 1 + 2 + 3
println(myList)
// MyList(3, 2, 1)
Solution 3
companion object
object MyList:
def apply[A](elements: A*): MyList[A] =
def build(elements: Seq[A], acc: MyList[A]): MyList[A] =
if elements.isEmpty then acc
else build(elements.tail, acc + elements.head)
build(elements.reverse, Empty())
In the companion object we add the apply method with a varargs param list.
In a tail recursive build function we add the elements to MyList with our own infix +
Because the recursive call will build the MyList in reversed order, we start with reversing the elements
main
@main
def main(): Unit =
val myList: MyList[Int] = MyList(1,2,3)
println(myList)
// MyList(1, 2, 3)