【问题标题】:Function which generically takes a type and returns the same type通常采用类型并返回相同类型的函数
【发布时间】:2012-04-04 21:29:32
【问题描述】:

我很难理解为什么 Scala 编译器对这个函数定义不满意:

def trimNonWordCharacters[T <: Iterable[String]](items: T): T =
     items map { _.replaceAll("\\W", "") }

这是REPL 的输出:

scala> def trimNonWordCharacters[T <: Iterable[String]](items: T): T =
     items map { _.replaceAll("\\W", "") }
<console>:5: error: type mismatch;
 found   : Iterable[java.lang.String]
 required: T
       def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") }

目标是传入 Iterable 的任何实现并获得相同类型的回退。这可能吗?

【问题讨论】:

  • @LuigiPlinge 这个问题不需要CanBuildFrom,因为filter 不需要它。这个问题非常相似,并且该问题的 title 肯定涵盖了它,但是这里需要更多的东西才能使它起作用。

标签: scala generics collections functional-programming type-theory


【解决方案1】:

Iterable 上的map 方法返回Iterable,因此即使TIterable 的子类,它的map 方法也将返回Iterable

为了更好地打字,你必须这样写:

import scala.collection.IterableLike
def trimNonWordCharacters[T <: Iterable[String]](items: T with IterableLike[String, T]): T =
     items map { _.replaceAll("\\W", "") }

但是,这也行不通,因为没有信息可以让T 上的地图生成另一个T。例如,将BitSet 映射到String 不会导致BitSet。所以我们需要其他东西:教如何从T 构建T,其中映射元素的类型为String。像这样:

import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
def trimNonWordCharacters[T <: Iterable[String]]
                         (items: T with IterableLike[String, T])
                         (implicit cbf: CanBuildFrom[T, String, T]): T =
     items map { _.replaceAll("\\W", "") }

【讨论】:

  • 非常感谢-您的解释非常有用,现在我终于知道了使用CanBuildFrom(!)的方法
【解决方案2】:

[作为答案输入而不是评论,因为 cmets 中的代码格式不正确]

@Daniel,感谢您的解释,我也发现它很有用。由于 Iterable 派生自 IterableLike,以下似乎也可以工作,并且稍微紧凑:

import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
def trimNonWordCharacters[T <: IterableLike[String, T]]
 (items: T)
 (implicit cbf: CanBuildFrom[T, String, T]): T =
 items map { _.replaceAll("\\W", "") }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    相关资源
    最近更新 更多