I have the following extension class that adds a myAppend
method to anything SeqLike
.
implicit class WithAppend[A, R](s: SeqLike[A, R]) extends AnyVal {
def myAppend(i: A)(implicit cbf: CanBuildFrom[R, A, R]): R = s :+ i
}
How can I port this code to Scala 2.13 and retain similar performance characteristics? Bonus points if the extended class can remain an AnyVal
Few things I have tried:
class Extends1[R, S <: IsSeq[R]](c: R, isSeq: S) {
def myAppend(a: isSeq.A): R = (isSeq(c) :+ a).asInstanceOf[R]
}
But the asInstanceOf
is disappointing - is it even safe?
I could do:
class Extends3[S[_], A](c: SeqOps[A, S, S[A]]) {
def myAppend(a: A): S[A] = c :+ a
}
but now we're constrained to collections of the form S[A]
while the Scala 2.12 code can take any R
.
Introduction to Scala List Append The following article provides an outline for Scala List Append. Scala list are immutable which means once assign object cannot change itself. List is also a part of collection which is used to store and retrieve elements.
Most Scala generic classes are collections, such as the immutable List, Queue, Set, Map, or their mutable equivalents, and Stack. Collections are containers of zero or more objects. We also have generic containers that aren’t so obvious at first. For example, Option is a container that can take zero objects or one object.
The most important changes in the Scala 2.13 collections library are: scala.Seq [+A] is now an alias for scala.collection.immutable.Seq [A] (instead of scala.collection.Seq [A] ). Note that this also changes the type of Scala varargs methods.
In Scala list represent linked list data structure. In a singly linked list structure we have node which contained two things data and address to the next node. We can modify the values present inside scala list programmatically through our logic. Also list can contain duplicate elements in it and maintain the insertion order as well.
I can come up with a method signature and implementation that works without casts:
implicit class WithAppend[Repr](private val repr: Repr) extends AnyVal {
def myAppend[A0, C](a: A0)(
implicit
isSeq: IsSeq[Repr]{ type A = A0 },
b: BuildFrom[Repr, A0, C]
): C = b.fromSpecific(repr)(isSeq(repr) :+ a)
}
It's hard to give guarantees about the performance of this, but I doubt it would be significantly worse than what you used to have. An alternative is b.newBuilder(repr).addAll(isSeq(repr)).addOne(a).result()
.
scala> List(1,2).myAppend(3)
res3: List[Int] = List(1, 2, 3)
scala> Vector(1,2).myAppend(3)
res4: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> "Strin".myAppend('g')
res5: String = String
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With