I am trying to understand mapConserve, which is said to be "Like xs map f, but returns xs unchanged if function f maps all elements to themselves," from List. Yet, it is giving out error.
def map [B] (f: (A) ⇒ B): List[B]
def mapConserve (f: (A) ⇒ A): List[A]
def mapConserve [B >: A <: AnyRef] (f: (A) ⇒ B): List[B]
scala> list map (x=>x)
res105: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> list mapConserve (x=>x)
<console>:12: error: inferred type arguments [Int] do not conform to method mapConserve's type parameter bounds [B >: Int <: AnyRef]
list mapConserve (x=>x)
^
The mapConserve code should satisfy the (A) => A function. If not, it still should satisfy the (A) => B function, since type A can be subtype and supertype of itself. Please enlighten me the purpose of mapConserve and the error.
Actually, mapConserve
is defined as
def mapConserve[A <: AnyRef](xs: List[A])(f: A => A): List[A]
def mapConserve[B >: A <: AnyRef](f: A => B): List[B]
so A
should be a subtype of AnyRef
. Int
is a subtype of AnyVal
, that brings an error.
scala> val l = List("foo", "bar", "baz")
l: List[java.lang.String] = List(foo, bar, baz)
scala> l.mapConserve(_.toUpperCase)
res4: List[java.lang.String] = List(FOO, BAR, BAZ)
scala> l.mapConserve(identity)
res5: List[java.lang.String] = List(foo, bar, baz)
The only difference between map
and mapConserve
, as it is described in the scaladoc:
Builds a new list by applying a function to all elements of this list. Like xs map f, but returns xs unchanged if function f maps all elements to themselves (as determined by eq).
scala> val xs = List.fill(1000000)("foo")
xs: List[java.lang.String] = List(foo, foo,...)
scala> xs.map(identity) eq xs
res48: Boolean = false
scala> xs.mapConserve(identity) eq xs
res49: Boolean = true
And xs mapConserve identity
is about five times faster in my simple benchmark.
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