【问题标题】:Creating an implicit function that wraps map() in Scala with the right type: Not for the faint at heart在 Scala 中创建一个以正确类型包装 map() 的隐式函数:不适合胆小的人
【发布时间】:2013-12-18 05:40:34
【问题描述】:

我正在尝试实现一个隐式函数mapMetered,它包装了map,并且在返回正确类型方面与它完全一样。我试过这个:

implicit class MeteredGenTraversablePimp[T, C[T] <: GenTraversable[T]](trav: C[T]) {
  def foreachMetered(m: Meter)(f: T => Unit) =
    m.foreach(trav)(f)

  def mapMetered[B, That](m: Meter)(f: (T) => B)(
    implicit bf: CanBuildFrom[C[T], B, That]
  ): That = {
    m.start()
    try {
      trav.map { x =>
        val z = f(x)
        m.item_processed()
        z
      } (bf)
    } finally { m.finish() }
  }
}

但是当我尝试这个时,我得到一个错误:

[info] Compiling 1 Scala source to /Users/benwing/devel/textgrounder/target/classes...
[error] /Users/benwing/devel/textgrounder/src/main/scala/opennlp/textgrounder/util/metering.scala:223: type mismatch;
[error]  found   : scala.collection.generic.CanBuildFrom[C[T],B,That]
[error]  required: scala.collection.generic.CanBuildFrom[scala.collection.GenTraversable[T],B,That]
[error]         } (bf)
[error]            ^
[error] one error found

有类似的 Stack Overflow 问题,包括 Daniel Sobral 提出的一个问题,他建议写 (trav: C[T] with GenTraversableLike[T]),但这并不能解决问题。

【问题讨论】:

  • 你做的和scala.collection.breakOut的功能类似吗(描述here)?
  • @DaoWen:不,我只是想创建一个行为类似于map 并返回正确类型的隐式函数。就我而言,这是map 的计量版本,它计算完成整个操作所需的时间、每次迭代的执行速度等。

标签: scala map implicit


【解决方案1】:

CanBuildFrom*Like 集合类型中的 Repr 参数已经用于表示最精确的集合类型。 您的问题的解决方案是包装 GenTraversableLike[A,Repr] 而不是 C[T]。 编译器会推断出确切的类型为Repr,一切都会完美无缺:

implicit class MeteredGenTraversablePimp[A, Repr](trav: GenTraversableLike[A,Repr]) {
  def foreachMetered(m: Meter)(f: A => Unit) = {
    m.start()
    try {
      trav.foreach{ e => f( e ); m.item_processed() }
    } finally {
      m.finish()
    }
  }

  def mapMetered[B, That](m: Meter)(f: A => B)(
    implicit bf: CanBuildFrom[Repr, B, That]
  ): That = {
    m.start()
    trav.map { x: A =>
      try {
        val z: B = f(x)
        m.item_processed()
        z
      } finally { m.finish() }
    }(bf)
  }
}

【讨论】:

猜你喜欢
  • 2011-04-27
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-30
  • 2018-02-23
  • 2014-01-07
相关资源
最近更新 更多