public interface Functor<A, FInst extends Functor<A,FInst>> { public <B, I extends Functor<B,FInst>> I fmap(F<A,B> f);}这段代码会产生错误,因为您在定义时
I将其定义为的子类
Functor<B,FInst>,但
Functor<B,FInst>在这种情况下FInst参数必须是的子类,而在上面将其定义为的子类
Functor<A,FInst>。由于
Functor<A,FInst>和
Functor<B,FInst>不兼容,因此会出现此错误。
我无法完全解决此问题,但我至少可以完成一半的工作:
import java.util.ArrayList;import java.util.List;interface F<A,R> { public R apply(A a);}interface Functor<A, FClass extends Functor<?, FClass>> { public <B> FClass fmap(F<A,B> f);}public class ListFunctor<A> implements Functor<A, ListFunctor<?>> { final private List<A> list; public ListFunctor(List<A> list) { this.list = list; } @Override public <B> ListFunctor<B> fmap(F<A,B> f) { List<B> result = new ArrayList<B>(); for(A a: list) result.add(f.apply(a)); return new ListFunctor<B>(result); }}这行得通,并且将允许的返回类型的集合适当地限制为ListFunctor,但并不将其限制为
ListFunctor<B>仅子类。您可以将其声明为returning
ListFunctor<A>或任何其他ListFunctor,并且仍然可以编译。但是您不能将其声明为返回FooFunctor或任何其他Functor。
解决其余问题的主要问题是,您不能将FClass限制为的子类
ListFunctor<B>,因为B参数是在方法级别而不是在类级别声明的,因此您不能编写
public class ListFunctor<A> implements Functor<A, ListFunctor<B>> {因为那时B并不意味着任何东西。我也无法使它与fmap()的第二个参数一起使用,但是即使可以,它也会强制您两次指定返回类型-
在type参数中指定一次,在返回类型本身中再指定一次。



