My goal is to implement the singleton value of algebraic data types (church-encoded) using the new scala 2.12 support for the SAM feature (single abstract method).
In Java, the following program returns true:
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface Maybe<A> {
<X> X fold(Supplier<X> empty, Function<A, X> just);
static <A, X> X empty0(Supplier<X> empty, Function<A, X> just) {
return empty.get();
}
static <A> Maybe<A> empty() {
return Maybe::empty0;
}
static void main(String[] args) {
Maybe<?> emptyString = Maybe.<String>empty();
Maybe<?> emptyInt = Maybe.<Integer>empty();
System.out.println(emptyString == emptyInt);
}
}
I tried porting this encoding to scala 2.12, but it does not compile:
@FunctionalInterface
trait Maybe[A] {
def fold[X](empty: => X, just: A => X): X
}
object Maybe {
def empty0[A, X](empty: => X, just: A => X): X = empty
def empty[A]: Maybe[A] = empty0(_ ,_) // does not compile
def main(args: Array[String]): Unit = {
val emptyString: Maybe[String] = Maybe.empty
val emptyInt: Maybe[Integer] = Maybe.empty
print(emptyString eq emptyInt) // how to make this print "true"???
}
}
The error I am getting is:
missing parameter type for expanded function ((x$1: <error>, x$2: <error>) => empty0(x$1, x$2))
My goal is to get a scalar run of the same optimization performed by Javac, which makes the java print "true" program. I am open to what is needed to meet scalac requirements if it does not use annotation asInstanceOfand Nothing/ variance.
EDIT. , scala ( !).