I am trying to use the Functional Java library.
I just include it in build.gradle
with
dependencies {
compile "org.functionaljava:functionaljava:4.8.1"
}
and compile using openjdk-15
and it just works... mostly.
The problem I have is the following:
I need to implement an interface
(fj.Ord.Definition
), which should be a functional interface - it has one non-default
method and many default
methods.
That means that an implementation via a lambda, or this
new Ord.Definition<MyClass>() {
@Override
public F<MyClass, Ordering> compare(MyClass a) {
return b -> a.myCompare(b);
}
}
should be fine.
What I get instead is:
Intellij: "Class 'Anonymous class derived from Definition' must either be declared abstract or implement abstract method 'compare(A, A)' in 'Definition'"
If I try to compile it anyway, javac: error: <anonymous MyClass$1> is not abstract and does not override abstract method ord()
This of course non only for the ord
, but for the other 11 default
methods as well.
If I try to implement them with Ord.Definition.super
as in
@Override
public F<A, A> prepend(A a1) {
return Ord.Definition.super(a1);
}
I get the error 'java.lang.Object' is not an inner class
.
To note here is that the functionaljava
library source code is full of these kinds of error (and many more) when viewed from Intellij in my project. Errors where Intellij complains about various mismatches between type variables and Object
are also common there.
So my questions are:
Ord.Definition
as a lambda, as the library intends (or at least by using its default
methods)?EDIT1: Per request, here are some chunks of the referenced fj.Ord.Definition
interface:
/**
* Tests for ordering between two objects.
*
* @version %build.number%
*/
public final class Ord<A> {
/**
* Primitives functions of Ord: minimal definition and overridable methods.
*/
public interface Definition<A> extends Equal.Definition<A>, Semigroup.Definition<A> {
F<A, Ordering> compare(A a);
default Ordering compare(A a1, A a2) {
return compare(a1).f(a2);
}
// equal:
@Override
default boolean equal(A a1, A a2) {
return compare(a1, a2) == Ordering.EQ;
}
...
@Override
default F<A, A> prepend(A a1) {
return apply((a2, o) -> o == Ordering.GT ? a1 : a2, compare(a1));
}
...
/**
* Build an ord instance from this definition.
* to be called after some successive {@link #then(F, Ord)} calls.
*/
default Ord<A> ord() {
return ordDef(this);
}
}
...
EDIT2: It turns out, in this case I can sidestep the issue by creating my ordering with either the method fj.Ord#ord(fj.F<A,fj.F<A,fj.Ordering>>)
or fj.Ord#ord(fj.F2<A,A,fj.Ordering>)
which each produce an Ord<A>
. That does however not answer the questions I posed.
You're using the wrong dependency. org.functionaljava:functionaljava
is retrofitted to work on Java 7 (and 6 according to the project docs). You need to use org.functionaljava:functionaljava-java8
instead:
dependencies {
implementation "org.functionaljava:functionaljava-java8:4.8.1"
}