Skip to content

IterableView#filterKeys and #mapValues cannot be chained #294

Closed
@NthPortal

Description

@NthPortal

With the current extension methods, (as of 2badce8), you cannot chain filterKeys and mapValues on an IterableView[_, _ <: Map]. I believe the reason for this is that both take a CanBuildFrom and return a That, unlike their corresponding 2.12 methods. The filterKeys extension is even particularly egregious, as filter methods always return the same type and do not ever take a CanBuildFrom.

The methods are currently defined as:

class MapViewExtensionMethods[K, V, C <: scala.collection.Map[K, V]](
    private val self: IterableView[(K, V), C])
    extends AnyVal {

  def mapValues[W, That](f: V => W)(
      implicit bf: CanBuildFrom[IterableView[(K, V), C], (K, W), That]): That =
    self.map[(K, W), That] { case (k, v) => (k, f(v)) }

  def filterKeys[That](p: K => Boolean)(
      implicit bf: CanBuildFrom[IterableView[(K, V), C], (K, V), That]): That =
    self.collect[(K, V), That] { case (k, v) if p(k) => (k, v) }
}

The following definitions do not use CanBuildFrom and can chain with each other:

class MapViewExtensionMethods[K, V, C <: scala.collection.Map[K, V]](
    private val self: IterableView[(K, V), C])
    extends AnyVal {

  def mapValues[W](f: V => W): IterableView[(K, W), C] =
    // the implementation of `self.map` also casts the result
    self.map({ case (k, v) => (k, f(v)) }).asInstanceOf[IterableView[(K, W), C]]

  def filterKeys(p: K => Boolean): IterableView[(K, V), C] =
    self.filter { case (k, _) => p(k) }
}

Unfortunately, mapValues has already been in previous releases, so its signature cannot be changed without a new release. However, we can still change the implementation of filterKeys (at least as of the aforementioned commit), as it has not been in any release yet. This allows the (I believe more common) use of .view.filterKeys(...).mapValues(...), though not .view.mapValues(...).filterKeys(...).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinglibraryRelated to compat library code (not rewrite rules)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions