Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why "++" works but "::" doesn't work even though they have same logic in scala

abstract class MyList[+A] {
    def head: A
    def next: MyList[A]
    def isEmpty: Boolean
    def add[B >: A](element: B): MyList[B]
    def printElements: String
    override def toString: String = s"[$printElements]"
    def ++[B >: A](list: MyList[B]): MyList[B]
    def ::[B >: A](list: MyList[B]): MyList[B]
}

case object Empty extends MyList[Nothing] {
    def head: Nothing = throw new NoSuchElementException
    def next: MyList[Nothing] = throw new NoSuchElementException
    def isEmpty: Boolean = true
    def add[B >: Nothing](element: B): MyList[B] = Cons(element, Empty)
    def printElements: String = ""
    def ++[B >: Nothing](list: MyList[B]): MyList[B] = list
    def ::[B >: Nothing](list: MyList[B]): MyList[B] = list
}

case class Cons[+A](h: A, t: MyList[A]) extends MyList[A] {
    def this(h: A) = this(h, Empty)
    def head: A = h
    def next: MyList[A] = t
    def isEmpty: Boolean = false
    def add[B >: A](element: B): MyList[B] = Cons(element, this)
    def printElements: String =
        if (t.isEmpty) s"$h"
        else s"$h ${t.printElements}"

    def ++[B >: A](list: MyList[B]): MyList[B] = Cons(h, next ++ list)
    def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next :: list)
}

object runTest extends App {
    val a = Empty.add(1).add(2).add(3)
    val b = Empty.add(4).add(5).add(6)
    println(a)
    println(b)
    println(a ++ b) //[3 2 1 6 5 4] good
    println(a :: b) //[6 3 5 2 4 1] why???
}

I tried to concat two MyList, but the problem is,
"++" and "::" have the same logic
but "++" will print [3 2 1 6 5 4], which makes sense, while "::" will prints [6 3 5 2 4 1]

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

From the 2.13 language specifications (I can’t seem to find the scala3 version, but this part hasn’t changed):

Operators ending in a colon ‘:’ are
right-associative. All other operators are left-associative.

[…]

If op is right-associative and its parameter is passed by name, the same operation is interpreted as e2.op(e1)


So your a :: b is the same as b.::(a), and

def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next :: list)

is

def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, list.::(next))

which explains the [6 3 5 2 4 1] you’re getting.

You can get the result you want by using

def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next.::(list))
...
println(a.::(b))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading