Ошибка вывода типа Scala

Я написал комбинированную функцию 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) => Логическое, фактическое: (Ничего) => Любое

Если я использую подсказку типа, хотя все компилируется нормально:

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

Почему типа B не выводится как Int от f?

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)
Другие вопросы по тегам