For interoperability, I need to pass a Scala PartialFunction from Java code. For Function (Function1 and so on), there is AbstractFunction that I can subclass with an anonymous type, but what would be the easiest way of doing the same for PartialFunction?
In this case, I would be happy to have it being a "complete" function in Java, appearing defined for all values, but typed as a PartialFunction.
Solution. A partial function is a function that does not provide an answer for every possible input value it can be given. It provides an answer only for a subset of possible data, and defines the data it can handle. In Scala, a partial function can also be queried to determine if it can handle a particular value.
When a function is not able to produce a return for every single variable input data given to it then that function is termed as Partial function. It can determine an output for a subset of some practicable inputs only. It can only be applied partially to the stated inputs.
What I would do here is provide an interface in Java, in some common library (which is not scala-aware):
//this is Java - in the Java lib
abstract class PartialTransformer<I, O> {
abstract public boolean isDefinedAt(I i);
public O transform(I i) {
if (isDefinedAt(i)) {
return transform0(i);
}
return null;
}
abstract protected O transform0(I i);
}
Then, in scala (i.e. a scala library dependent on the above Java library), convert an implementation of this to a PartialFunction
:
//this is scala - in the scala lib
object MyPartialFunctions {
def fromPartialTransformer[I, O](t: PartialTransformer[I, O]) = new PartialFunction[I, O] {
def isDefinedAt(i: I) = t isDefinedAt i
def apply(i: I) = {
val r = t transform i
if (r eq null) throw new MatchError
else r
}
}
}
Then your Java code can do this:
//This is Java - in your client code
MyPartialFunctions$.MODULE$.fromPartialTransformer(new PartialTransformer<Integer, String>() {
@Override public boolean isDefinedAt(Integer i) { /* */ }
@Override protected String transform0(Integer i) { /* */ }
}
If you don't like the MyPartialFunctions$.MODULE$
syntax, it's possible in the scala library, a Java class which hides this from you:
//This is Java - in the scala-lib
public class ScalaUtils {
public <I, O> scala.PartialFunction<I, O> toPartialFunction(PartialTransformer<I, O> t) {
MyPartialFunctions$.MODULE$.fromPartialTransformer(t);
}
}
Then your call-site looks like this:
//This is Java - in your client code
ScalaUtils.toPartialFunction(new PartialTransformer<Integer, String>() {
@Override public boolean isDefinedAt(Integer i) { /* */ }
@Override protected String transform0(Integer i) { /* */ }
}
This involves, ahem, a few levels of indirection!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With