Почему на PartialFunction нет метода orElse, который принимает общую функцию?

Почему нет метода со следующей сигнатурой в классе PartialFunction[A, B]?

def orElse[A1 <: A, B1 >: B](that: A1 => B1): A1 => B1

Есть ли какая-то логическая причина отсутствия этого метода, или это был простой надзор?

Ответ 1

  • Поскольку тривиально добиться этого, подняв частичную функцию

    partialFunc.lift(arg) getOrElse (totalFunc(arg))

  • Поскольку Scala, как правило, пытается избежать перегрузки

  • Потому что никто не думал добавить его, и он, вероятно, пока не понадобился

  • Поскольку каждый метод, добавленный в стандартную библиотеку, несет все возрастающую стоимость с точки зрения обслуживания ниже по течению

Ответ 2

Рассмотрим,

scala> object O {
     |   def f(g: Int => Int) = g(1)
     |   def f(g: PartialFunction[Int, Int]) = g(2).toString
     | }
defined module O

scala> O f { _ * 1 }
res3: Int = 1

Итак, как вы теперь связываете частичные функции? Или, другими словами, если описанная выше перегрузка была в библиотеке, и я написал это:

type PF = PartialFunction[Any, Int]
val pf1: PF = { case n: Int => n }
val pf2: PF = pf1 orElse { case x: String => x.length }
val pf3: PF = pf2 orElse { case d: Double => d.toInt }

Я получил сообщение об ошибке pf2 из-за неоднозначности типа. Если вместо этого я пишу:

val pf2 = pf1 orElse ((_: Any) match { case x: String => x.length })
val pf3 = pf2 orElse ((_: Any) match { case d: Double => d.toInt })

Затем я получаю сообщение об ошибке pf3, потому что pf2 будет Function1.

Ответ 3

Похоже, нет никакой веской причины для отсутствия этих функций в стандартной библиотеке, кроме надзора или, возможно, никто не нуждается в них так часто, как в стандартной библиотеке.

Я определил неявное преобразование от A => B до PartialFunction[A, B], которое, похоже, позаботится об этом и других подобных случаях и не приводит к неблагоприятным последствиям.

scala> implicit def fToPf[A, B](f: A => B) = new PartialFunction[A, B] {
     |   def isDefinedAt(a: A) = true
     |   def apply(a: A) = f(a)
     | }
fToPf: [A, B](f: A => B)java.lang.Object with PartialFunction[A,B]