Scala total function as partial function
Asked Answered
M

5

9

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
}
Monopolist answered 2/1, 2014 at 20:8 Comment(2)
Note that there is a PartialFunction.apply method: def partial = PartialFunction[Any,Any]{ any => any }Hacking
@senia, you should enter your comment as the answer as I believe it's correct and should be what the op is looking forOvation
H
12

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 }
Hacking answered 2/1, 2014 at 20:32 Comment(7)
I'm going to upvote this because I did not know you could do that, but it's still not quite what I was hoping for. I think this is probably more work than just doing { case any => any } right. This apply is probably very useful when you already have a function rather than defining inline I guess.Monopolist
I always try and use language features if they fit my needs first before writing my own code instead. I guess you just need to determine if this fits your needs or not...Ovation
I don't really have any needs in this case (excuse the pun :)). I was just writing a partial function today that simply returned the input, and I thought an inline total function would have been nice. I ended up doing case { any => any} but I would it would make a good SO question.Monopolist
@monkjack: You'll use it in case if you already have a function (PartialFunction{identity}) or if you want to use it as part of expression: partail orElse pf(identity).Hacking
hi, I know it's an old question, but could anyone come up with a reason of NOT having that conversion available implicitly? So if I have sth like that in scope implicit def lift[I, O](f: Function1[I,O]): PartialFunction[I,O] = PartialFunction(f). Could I shoot myself in the foot with this?Mastodon
As of Scala 2.13.5 a PartialFunction.fromFunction(identity[String] _) will do the trick whilst PartialFunction(identity) results in PartialFunction.type does not take parameters.Bluejacket
A more concise way that works for Scala 2.13.5 is (identity[String] _): PartialFunction[String, String] or (identity[String] _): String =/> String if you import scala.{PartialFunction => =/>}Bluejacket
O
4

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.

Overwind answered 2/1, 2014 at 20:45 Comment(0)
S
1

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) }
Strasbourg answered 6/1, 2014 at 16:0 Comment(2)
Thanks for the reply. I do have the concepts the correct way though, as I was referring to the fact a total function is a specialized case of a partial function (in general math not in Scala), so if you ask for a partial function, I should be able to give you a total function as that still fulfils the criteria. It was really just a kind of off the cuff, I wonder if, type of question, could I do ( any => any ) instead of case { any => any }. I really am turning into a Scala-zealot when I'm worried about saving a few characters :)Monopolist
Gotcha - you're coming at it from the mathematics point of view. I thought you were thinking about the OO p.o.v.Strasbourg
B
1

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.

Bluejacket answered 12/4, 2021 at 12:36 Comment(0)
B
-4

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

Bonn answered 2/1, 2014 at 20:14 Comment(4)
Your answer is backwards. The op is looking for a facility to turn a total function into a partial function and not the other way around.Ovation
PartialFunction is indeed a subtype of Function in scala land, but in maths land a total function is a special case of a partial function.Monopolist
The question is not ambiguous at all.Monopolist
can you pls explain? cause i had in mind exactly what you said.Bonn

© 2022 - 2024 — McMap. All rights reserved.