Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between `::` and `+:` for prepending to a list)?

List has 2 methods that are specified to prepend an element to an (immutable) list:

  • +: (implementing Seq.+:), and
  • :: (defined only in List)

+: technically has a more general type signature—

def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That def ::[B >: A](x: B): List[B] 

—but ignoring the implicit, which according to the doc message merely requires That to be List[B], the signatures are equivalent.

What is the difference between List.+: and List.::? If they are in fact identical, I assume +: would be preferred to avoid depending on the concrete implementation List. But why was another public method defined, and when would client code call it?

Edit

There is also an extractor for :: in pattern matching, but I'm wondering about these particular methods.

See also: Scala list concatenation, ::: vs ++

like image 736
Mechanical snail Avatar asked Aug 05 '12 07:08

Mechanical snail


People also ask

What's the difference between the list methods append() and extend()?

append() adds a single element to the end of the list while . extend() can add multiple individual elements to the end of the list.

What is the difference between += and append?

For a list, += is more like the extend method than like the append method. With a list to the left of the += operator, another list is needed to the right of the operator. All the items in the list to the right of the operator get added to the end of the list that is referenced to the left of the operator.

What is difference between append and add?

@toron Adding means putting two or more things together, such as numbers for example. Appending implies that you are attaching something to a main item. A book may have an appendix which usually gives extra information.

How do I append to a list in Scala?

This is the first method we use to append Scala List using the operator “:+”. The syntax we use in this method is; first to declare the list name and then use the ':+' method rather than the new element that will be appended in the list. The syntax looks like “List name:+ new elements”.


1 Answers

The best way to determine the difference between both methods is to look it the source code.

The source of :::

def ::[B >: A] (x: B): List[B] =   new scala.collection.immutable.::(x, this) 

The source of +::

override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That = bf match {   case _: List.GenericCanBuildFrom[_] => (elem :: this).asInstanceOf[That]   case _ => super.+:(elem)(bf) } 

As you can see, for List, both methods do one and the same (the compiler will choose List.canBuildFrom for the CanBuildFrom argument).

So, which method to use? Normally one would choose the interface (+:) than the implementation (::) but because List is a general data structure in functional languages it has its own methods which are widely used. Many algorithms are build up the way how List works. For example you will find a lot of methods which prepend single elements to List or call the convenient head or tail methods because all these operations are O(1). Therefore, if you work locally with a List (inside of single methods or classes), there is no problem to choose the List-specific methods. But if you want to communicate between classes, i.e. you want to write some interfaces, you should choose the more general Seq interface.

like image 96
kiritsuku Avatar answered Oct 01 '22 08:10

kiritsuku