Mix-in trait to enable DefaultSerializationProxy for the standard collection types. Depending on the type it is mixed into, it will dynamically choose iterableFactory
, mapFactory
, sortedIterableFactory
or sortedMapFactory
for deserialization into the respective CC
type. Override writeReplace
or implement it directly without using this trait if you need a non-standard factory or if you want to use a different serialization scheme.
The default serialization proxy for collection implementations.
This class is final
and requires an extra Factory
object rather than leaving the details of creating a Builder
to an abstract method that could be implemented by a subclass. This is necessary because the factory is needed for deserializing this class's private state, which happens before any subclass fields would be deserialized. Any additional state required to create the proper Builder
needs to be captured by the factory
.
A trait which can be used to avoid code duplication when defining extension methods that should be applicable both to existing Scala collections (i.e., types extending Iterable
) as well as other (potentially user-defined) types that could be converted to a Scala collection type. This trait makes it possible to treat Scala collections and types that can be implicitly converted to a collection type uniformly. For example, one can provide extension methods that work both on collection types and on String
s (String
s do not extend Iterable
, but can be converted to Iterable
)
IsIterable
provides three members:
A
, which represents the element type of the target Iterable[A]
type member C
, which represents the type returned by transformation operations that preserve the collection’s elements typemethod apply
, which provides a way to convert between the type we wish to add extension methods to, Repr
, and IterableOps[A, Iterable, C]
.One must provide IsIterable
as an implicit parameter type of an implicit conversion. Its usage is shown below. Our objective in the following example is to provide a generic extension method mapReduce
to any type that extends or can be converted to Iterable
. In our example, this includes String
.
import scala.collection.{Iterable, IterableOps} import scala.collection.generic.IsIterable class ExtensionMethods[Repr, I <: IsIterable[Repr]](coll: Repr, it: I) { def mapReduce[B](mapper: it.A => B)(reducer: (B, B) => B): B = { val iter = it(coll).iterator var res = mapper(iter.next()) while (iter.hasNext) res = reducer(res, mapper(iter.next())) res } } implicit def withExtensions[Repr](coll: Repr)(implicit it: IsIterable[Repr]): ExtensionMethods[Repr, it.type] = new ExtensionMethods(coll, it) // See it in action! List(1, 2, 3).mapReduce(_ * 2)(_ + _) // res0: Int = 12 "Yeah, well, you know, that's just, like, your opinion, man.".mapReduce(x => 1)(_ + _) // res1: Int = 59
Here, we begin by creating a class ExtensionMethods
which contains our mapReduce
extension method.
Note that ExtensionMethods
takes a constructor argument coll
of type Repr
, where Repr
represents (typically) the collection type, and an argument it
of a subtype of IsIterable[Repr]
. The body of the method starts by converting the coll
argument to an IterableOps
in order to call the iterator
method on it. The remaining of the implementation is straightforward.
The withExtensions
implicit conversion makes the mapReduce
operation available on any type Repr
for which it exists an implicit IsIterable[Repr]
instance. Note how we keep track of the precise type of the implicit it
argument by using the it.type
singleton type, rather than the wider IsIterable[Repr]
type. We do that so that the information carried by the type members A
and C
of the it
argument is not lost.
When the mapReduce
method is called on some type of which it is not a member, implicit search is triggered. Because implicit conversion withExtensions
is generic, it will be applied as long as an implicit value of type IsIterable[Repr]
can be found. Given that the IsIterable
companion object contains implicit members that return values of type IsIterable
, this requirement is typically satisfied, and the chain of interactions described in the previous paragraph is set into action. (See the IsIterable
companion object, which contains a precise specification of the available implicits.)
Note: Currently, it's not possible to combine the implicit conversion and the class with the extension methods into an implicit class due to limitations of type inference.
IsIterable
for New TypesOne must simply provide an implicit value of type IsIterable
specific to the new type, or an implicit conversion which returns an instance of IsIterable
specific to the new type.
Below is an example of an implementation of the IsIterable
trait where the Repr
type is Range
.
implicit val rangeRepr: IsIterable[Range] { type A = Int; type C = IndexedSeq[Int] } = new IsIterable[Range] { type A = Int type C = IndexedSeq[Int] def apply(coll: Range): IterableOps[Int, IndexedSeq, IndexedSeq[Int]] = coll }
(Note that in practice the IsIterable[Range]
instance is already provided by the standard library, and it is defined as an IsSeq[Range]
instance)
Type class witnessing that a collection representation type Repr
has elements of type A
and has a conversion to IterableOnce[A]
.
This type enables simple enrichment of IterableOnce
s with extension methods which can make full use of the mechanics of the Scala collections framework in their implementation.
Example usage,
class FilterMapImpl[Repr, I <: IsIterableOnce[Repr]](coll: Repr, it: I) { final def filterMap[B, That](f: it.A => Option[B])(implicit bf: BuildFrom[Repr, B, That]): That = { val b = bf.newBuilder(coll) for(e <- it(coll).iterator) f(e) foreach (b +=) b.result() } } implicit def filterMap[Repr](coll: Repr)(implicit it: IsIterableOnce[Repr]): FilterMapImpl[Repr, it.type] = new FilterMapImpl(coll, it) List(1, 2, 3, 4, 5) filterMap (i => if(i % 2 == 0) Some(i) else None) // == List(2, 4)
2.10
Type class witnessing that a collection type Repr
has keys of type K
, values of type V
and has a conversion to MapOps[K, V, Iterable, C]
, for some types K
, V
and C
.
This type enables simple enrichment of Map
s with extension methods.
Collection type (e.g. Map[Int, String]
)
Type class witnessing that a collection representation type Repr
has elements of type A
and has a conversion to SeqOps[A, Iterable, C]
, for some types A
and C
.
This type enables simple enrichment of Seq
s with extension methods which can make full use of the mechanics of the Scala collections framework in their implementation.
© 2002-2019 EPFL, with contributions from Lightbend.
Licensed under the Apache License, Version 2.0.
https://www.scala-lang.org/api/2.13.0/scala/collection/generic/index.html