I want to define a Functor class in Java. This works:
//a Function
public interface F {
public R apply(A a);
}
public interface Functor {
public interface Functor> {
public > I fmap(F f);
}
This code generates an error because when you define I
, you define it to be a subclass of Functor
, but the FInst parameter must be a subclass of Functor
in this case, while it is defined above as being a subclass of Functor
. Since Functor
and Functor
aren't compatible, you get this error.
I haven't been able to solve this completely, but I could do at least a half of the job:
import java.util.ArrayList;
import java.util.List;
interface F {
public R apply(A a);
}
interface Functor> {
public FClass fmap(F f);
}
public class ListFunctor implements Functor> {
final private List list;
public ListFunctor(List list) {
this.list = list;
}
@Override
public ListFunctor fmap(F f) {
List result = new ArrayList();
for(A a: list) result.add(f.apply(a));
return new ListFunctor(result);
}
}
This works, and it properly limits the set of allowed return types to ListFunctor, but it doesn't limit it to subclasses of ListFunctor
only. You could declare it as returning ListFunctor
or any other ListFunctor, and it would still compile. But you can't declare it as returning a FooFunctor or any other Functor.
The main problem with solving the rest of the problem is that you can't limit FClass to subclasses of ListFunctor
only, as the B parameter is declared at the method level, not at the class level, so you can't write
public class ListFunctor implements Functor> {
because B doesn't mean anything at that point. I couldn't get it working with the second parameter to the fmap() either, but even if I could, it would just force you to specify the return type twice - once in the type parameter and once more as the return type itself.