【发布时间】:2015-11-10 17:55:39
【问题描述】:
我正在使用“完全懒惰”并且我希望在我正在编写的程序中使用Either<String,Option<A>>。这是一个使用 Monad Transformer for Option 的好地方(类似于 Scalaz 7 中的真棒)。我似乎无法在 Java 8 中正确使用泛型。下面的代码是我希望它看起来的样子(作为开始)。任何关于如何让它工作/编译的建议都会很棒!!!请帮助我让这个 Monad Transformer 存在于我的 Java 8 代码中。
import com.googlecode.totallylazy.Monad;
import com.googlecode.totallylazy.Option;
import com.googlecode.totallylazy.functions.Function1;
import static com.google.common.base.Preconditions.checkNotNull;
public class OptionT<M extends Monad,A> {
final M<Option<A>> run;
public OptionT(final M<Option<A>> run){
this.run = checkNotNull(run);
}
public <B> OptionT<M,B> map(Function1<A,B> f){
return new OptionT<M,B>(run.map(o-> o.map(f)));
}
}
编辑:我得到以下编译器故障:
OptionT.java:15: error: unexpected type
final M<A> run;
^
required: class
found: type parameter M
where M is a type-variable:
M extends Monad<Option<?>> declared in class OptionT
OptionT.java:17: error: unexpected type
public OptionT(final M<A> run){
^
required: class
found: type parameter M
where M is a type-variable:
M extends Monad<Option<?>> declared in class OptionT
【问题讨论】:
-
怎么不工作?
-
您不能将泛型参数传递给 Java 中的泛型参数(
M<?>,其中 M 是泛型)。这不会直接从 Scala 翻译过来;它们是截然不同的语言。 -
Java 的类型系统不支持更高种类的类型。你不能这样做。
-
有没有办法“解决”这个限制?
<M extends Monad<Option<A>>,A>之类的东西?我尝试了类似的方法,但不能保证M在map的类型签名中保持不变。 :( -
我的猜测是,无论你想出什么都将是丑陋和冗长的,以至于没有用处(与非单调地做相比)。 Java 并不是为这种高度功能化的编码风格而设计的。它可以很好地完成简单的事情(映射、基本转换等),但是当您进入 FP 的类型系统方面(monads、currying 等)时,它开始看起来越来越像面向对象编程,即它到底是什么。
标签: java generics functional-programming java-8 monad-transformers