سؤال

Since a total function is a special case of a partial function, I think I should be able to return a function when I need a partial.

Eg,

def partial : PartialFunction[Any,Any] = any => any

Of course this syntax fails to compile. My question is, is it possible to do this, and if so what do I need to do to get the syntax right.

I know I can do the following, but this is just an out-of-curiousity-question

def partial : PartialFunction[Any,Any] = {
  case any => any
}
هل كانت مفيدة؟

المحلول

You could use PartialFunction.apply method:

val partial = PartialFunction[Any,Any]{ any => any }

You could import this method if you want to make it shorter:

import PartialFunction.{apply => pf}
val partial = pf[Any,Any]{ any => any }

نصائح أخرى

A FunctionN is not a total function:

val evilFun: Int => Int = n => if (n < 0) sys.error("I'm evil!") else n

In other words, all Scala functions are partial functions. Therefore PartialFunction just gives you a way to inspect the partial function via isDefinedAt and chain partial functions via orElse.

It could make sense to get rid of PartialFunction altogether and have isDefinedAt at the level of FunctionN with function literals and lifted methods implementing isDefinedAt as always true.

I think you may have the concept switched.

PartialFunction[-A, +B] extends (A) ⇒ B 

However, you can't use a superclass value where a subclass is expected because the subclass is more specific. So you can't return a Function1 value from a method typed to return a PartialFunction.

The inverse works though - you can use a subclass where a superclass is expected. So you can return a PartialFunction from a method typed to return a Function1 (with the same type parameters):

scala> def f: Any => Any = { case a => "foo" }
f: Any => Any

scala> f(1)
res0: Any = foo

In this particular case you can always convert a Function to a PartialFunction, so the PartialFunction.apply method is provided.

def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) }

Time has moved on, Scala is at 2.13.5 and what is shown in the accepted answer is deprecated since Scala 2.12.5:

For converting an ordinary function f to a partial function pf, use val pf: PartialFunction[A, B] = { case x => f(x) }. For creating a new PartialFunction, use an explicit type annotation instead, like in val pf: PartialFunction[Int, String] = { case 1 => "one" }.

Also, consider the import scala.{PartialFunction => =/>} (in contrast to regular, total, functions =>). Since partial functions require writing out the type (aka adding type annotations) this saves you a lot of manual typing and improves readability, e.g.:

val yourPf: String =/> String = {
  case SomeRegEx(s) => s
}

Side note: On my machine PartialFunction.apply even results in the error PartialFunction.type does not take parameters.

i think youre looking for the convenience method called "lift" which turns a partialfunction into a function1 (returning the result wrapped in an option).

http://www.scala-lang.org/api/current/index.html#scala.PartialFunction

speaking of the taxonomy; i think you got that backwards - a partialfunction is a subtype of function1

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top