Полная функция Скалы как частичная функция
Так как функция итога - это особый случай частичной функции, я думаю, что я смогу вернуть функцию, когда мне понадобится частичная функция.
Например,
def partial : PartialFunction[Any,Any] = any => any
Конечно, этот синтаксис не компилируется. У меня вопрос, возможно ли это сделать, и если да, что мне нужно сделать, чтобы получить правильный синтаксис.
Я знаю, что могу сделать следующее, но это просто вопрос из любопытства
def partial : PartialFunction[Any,Any] = {
case any => any
}
5 ответов
Вы могли бы использовать PartialFunction.apply
метод:
val partial = PartialFunction[Any,Any]{ any => any }
Вы можете импортировать этот метод, если хотите сократить его:
import PartialFunction.{apply => pf}
val partial = pf[Any,Any]{ any => any }
FunctionN
не является полной функцией:
val evilFun: Int => Int =
n => if (n < 0) sys.error("I'm evil!") else n
Другими словами, все функции Scala являются частичными функциями. Следовательно PartialFunction
просто дает вам возможность проверить частичную функцию через isDefinedAt
и цепочка частичных функций через orElse
,
Это может иметь смысл избавиться от PartialFunction
в целом и есть isDefinedAt
на уровне FunctionN
с функциональными литералами и поднял методы реализации isDefinedAt
как всегда true
,
Я думаю, что вы можете сменить концепцию.
PartialFunction[-A, +B] extends (A) ⇒ B
Однако вы не можете использовать значение суперкласса, когда ожидается, что подкласс более специфичен. Так что вы не можете вернуть Function1
значение из метода, введенного для возврата PartialFunction
,
Обратное работает, хотя - вы можете использовать подкласс, где ожидается суперкласс. Таким образом, вы можете вернуть PartialFunction
из метода, набранного для возврата Function1
(с однотипными параметрами):
scala> def f: Any => Any = { case a => "foo" }
f: Any => Any
scala> f(1)
res0: Any = foo
В этом конкретном случае вы всегда можете преобразовать Function
к PartialFunction
, Итак PartialFunction.apply
метод предоставляется.
def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }
Время прошло , Scala находится на уровне 2.13.5, а то, что показано в принятом ответе , устарело, начиная с Scala 2.12.5:
Для преобразования обычной функции f в частичную функцию pf используйте
val pf: PartialFunction[A, B] = { case x => f(x) }
. Для создания новой PartialFunction используйте вместо этого явную аннотацию типа, как вval pf: PartialFunction[Int, String] = { case 1 => "one" }
.
Также рассмотрите
import scala.{PartialFunction => =/>}
(в отличие от обычных, тотальных, функций
=>
). Поскольку частичные функции требуют записи типа (также как и добавление аннотаций к типу), это избавляет вас от необходимости печатать вручную и улучшает читаемость, например:
val yourPf: String =/> String = {
case SomeRegEx(s) => s
}
Боковое примечание: на моей машине
PartialFunction.apply
даже приводит к ошибке
PartialFunction.type does not take parameters
.
Я думаю, что вы ищете удобный метод, называемый "lift", который превращает частичную функцию в функцию1 (возвращая результат, заключенный в опцию).
http://www.scala-lang.org/api/current/index.html
говоря о таксономии; я думаю, что вы получили это задом наперед - частичная функция является подтипом функции1