Packages

package generic

Source
package.scala
Linear Supertypes
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. generic
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. trait IsIterableLike[Repr] extends AnyRef

    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.

    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 Strings (Strings do not extend Iterable, but can be converted to Iterable)

    IsIterableLike provides two members:

    1. type member A, which represents the element type of the target Iterable[A]
    2. value member conversion, which provides a way to convert between the type we wish to add extension methods to, Repr, and Iterable[A].
    Usage

    One must provide IsIterableLike 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
      import scala.collection.generic.IsIterableLike
    
      class ExtensionMethods[A, Repr](coll: IterableLike[A, Repr]) {
        def mapReduce[B](mapper: A => B)(reducer: (B, B) => B): B = {
          val iter = coll.toIterator
          var res = mapper(iter.next())
          while (iter.hasNext)
            res = reducer(res, mapper(iter.next()))
          res
        }
      }
    
      implicit def withExtensions[Repr](coll: Repr)(implicit Iterable: IsIterableLike[Repr]) =
        new ExtensionMethods(Iterable.conversion(coll))
    
    // 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 IterableLike[A, Repr], where A represents the element type and Repr represents (typically) the collection type. The implementation of mapReduce itself is straightforward.

    The interesting bit is the implicit conversion withExtensions, which returns an instance of ExtensionMethods. This implicit conversion can only be applied if there is an implicit value Iterable of type IsIterableLike[Repr] in scope. Since IsIterableLike provides value member conversion, which gives us a way to convert between whatever type we wish to add an extension method to (in this case, Repr) and IterableLike[A, Repr], we can now convert coll from type Repr to IterableLike[A, Repr]. This allows us to create an instance of the ExtensionMethods class, which we pass our new IterableLike[A, Repr] to.

    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 IsIterableLike[Repr] can be found. Given that IsIterableLike contains implicit members that return values of type IsIterableLike, this requirement is typically satisfied, and the chain of interactions described in the previous paragraph is set into action. (See the IsIterableLike 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.

    Implementing IsIterableLike for New Types

    One must simply provide an implicit value of type IsIterableLike specific to the new type, or an implicit conversion which returns an instance of IsIterableLike specific to the new type.

    Below is an example of an implementation of the IsIterableLike trait where the Repr type is String.

    implicit val stringRepr: IsIterableLike[String] { type A = Char } =
      new IsIterableLike[String] {
        type A = Char
        val conversion = implicitly[String => IterableOps[Char, Any, String]]
      }
  2. trait IsSeqLike[Repr] extends AnyRef

    Type class witnessing that a collection representation type Repr has elements of type A and has a conversion to SeqOps[A, Seq, Repr].

    Type class witnessing that a collection representation type Repr has elements of type A and has a conversion to SeqOps[A, Seq, Repr].

    This type enables simple enrichment of Seqs with extension methods which can make full use of the mechanics of the Scala collections framework in their implementation.

    See also

    scala.collection.generic.IsIterableLike

  3. type CanBuildFrom[-From, -A, +C] = BuildFrom[From, A, C]
    Annotations
    @deprecated
    Deprecated

    (Since version 2.13.0) Use scala.collection.BuildFrom instead

  4. type Clearable = mutable.Clearable
    Annotations
    @deprecated
    Deprecated

    (Since version 2.13.0) Clearable was moved from collection.generic to collection.mutable

Value Members

  1. object IsIterableLike
  2. object IsSeqLike

Inherited from AnyRef

Inherited from Any

Ungrouped