IsIterable

scala.collection.generic.IsIterable
See theIsIterable companion object
transparent trait IsIterable[Repr] extends IsIterableOnce[Repr]

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 uniformly treat Scala collections and types that can be implicitly converted to a collection type. 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.)

IsIterable provides three members:

  1. type member A, which represents the element type of the target Iterable[A]
  2. type member C, which represents the type returned by transformation operations that preserve the collection’s element type
  3. method apply, which provides a way to convert between the type we wish to add extension methods to, Repr, and IterableOps[A, Iterable, C].

Usage

One must provide IsIterable as an implicit parameter of the extension method. Its usage is shown below. Our objective in the following example is to provide a generic extension method mapReduce for any type that extends or can be converted to Iterable, such as String.

  import scala.collection.generic.IsIterable

  extension [Repr, I <: IsIterable[Repr]](coll: Repr)(using 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
    }

// 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

The extension method takes a receiver coll of type Repr, where Repr typically represents 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 rest of the implementation is straightforward.

The mapReduce extension method is available on any type Repr for which there is an implicit IsIterable[Repr] instance. The companion object for IsIterable provides an instance for types that are already an IterableOps.

Implementing IsIterable for New Types

For a custom type, one need only provide an implicit value of type IsIterable that specifies the element type, the collection type, and an implementation of apply that converts the collection to an IterableOps.

Below is an example implementation of the IsIterable trait where the Repr type is Range. In practice, IsIterable[Range] is already provided by the implicit value for any IterableOps, as for List in the previous example. Similarly, the instance for String was available because the library provides an IsSeq[String].

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
 }

Attributes

Companion
object
Source
IsIterable.scala
Graph
Supertypes
trait IsIterableOnce[Repr]
class Object
trait Matchable
class Any
Known subtypes
trait IsMap[Repr]
trait IsSeq[Repr]

Members list

Type members

Types

type A
Implicitly added by isIterableLikeIsIterableOnce

The type of elements we can traverse over (e.g. Int).

The type of elements we can traverse over (e.g. Int).

Attributes

Source
IsIterableOnce.scala
type C

The type returned by transformation operations that preserve the same elements type (e.g. filter, take).

The type returned by transformation operations that preserve the same elements type (e.g. filter, take).

In practice, this type is often Repr itself, except in the case of SeqView[A] (and other View[A] subclasses), where it is View[A].

Attributes

Source
IsIterable.scala

Inherited and Abstract types

type A

The type of elements we can traverse over (e.g. Int).

The type of elements we can traverse over (e.g. Int).

Attributes

Inherited from:
IsIterableOnce
Source
IsIterableOnce.scala

Value members

Abstract methods

def apply(coll: Repr): IterableOnce[A]
Implicitly added by isIterableLikeIsIterableOnce

A conversion from the representation type Repr to a IterableOnce[A].

A conversion from the representation type Repr to a IterableOnce[A].

Attributes

Source
IsIterableOnce.scala
def apply(coll: Repr): IterableOps[A, Iterable, C]

A conversion from the type Repr to IterableOps[A, Iterable, C].

A conversion from the type Repr to IterableOps[A, Iterable, C].

Attributes

Source
IsIterable.scala

Deprecated fields

val conversion: Repr => IterableOnce[A]
Implicitly added by isIterableLikeIsIterableOnce

Attributes

Deprecated
[Since version 2.13.0] \'conversion\' is now a method named \'apply\'
Source
IsIterableOnce.scala
override val conversion: Repr => IterableOps[A, Iterable, C]

Attributes

Deprecated
[Since version 2.13.0] \'conversion\' is now a method named \'apply\'
Source
IsIterable.scala