1

我编写了一个组合的 map-and-find 函数,它将函数应用于 Iterable 并返回谓词为 true 的第一个映射结果:

implicit class EnhancedIterable[A, B[X] <: Iterable[X]](it: B[A]) {

  def mapAndFind[B](f: A => B, p: B => Boolean): Option[B] = {
    var result: Option[B] = None
    for (value <- it if result.isEmpty) {
      val r = f(value)
      if (p(r))
        result = Some(r)
    }
    result
  }

}

问题是当我尝试按预期使用该函数时遇到编译错误:

val names = Seq("Jose", "Chris", "Carlos", "Stephan")

names.mapAndFind(
  _.length,
  _ > 5 // Error
)

类型不匹配,预期:(NotInferedB) => Boolean,实际:(Nothing) => Any

如果我使用类型提示,尽管事情编译得很好:

names.mapAndFind(
  _.length,
  (len: Int) => len > 5
)

为什么 typeB不能推断为Intfrom f

4

1 回答 1

1

Scala 中的类型推断在参数列表之间流动,而不是在它们内部。

你可以写:

implicit class EnhancedIterable[A, B[X] <: Iterable[X]](it: B[A]) {
  def mapAndFind[B](f: A => B)(p: B => Boolean): Option[B] = {
    var result: Option[B] = None
    for (value <- it if result.isEmpty) {
      val r = f(value)
      if (p(r)) result = Some(r)
    }
    result
  }
}

接着:

val names = Seq("Jose", "Chris", "Carlos", "Stephan")
names.mapAndFind(_.length)(_ > 5)

产量:

Some(6)
于 2017-09-17T15:44:02.500 回答