我正在使用“完全懒惰”,我希望在我正在编写的程序中使用Either<String,Option<A>>
。这是一个使用Monad Transformer for Option的好地方(类似于Scalaz 7中存在的那个很棒)。我似乎无法在Java 8中使用Generics。下面的代码是我喜欢它的样子(一开始)。任何关于如何让它工作/编译的建议都是惊人的!!!请帮我把这个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
答案 0 :(得分:2)
您可以使用cyclops-monad-api执行此操作,有一个介绍性blog post that you might find helpful here。我是图书馆和博客文章的作者。
我已经在下面发布了您的示例的工作实现(对于JDK 8可选) -
public class OptionT<A> {
@Getter
final AnyM<Optional<A>> run;
public OptionT(final AnyM<Optional<A>> run){
this.run = run;
}
public <B> OptionT<B> map(Function<A,B> f){
return new OptionT<B>(run.map(o-> o.map(f)));
}
}
@Test
public void test() {
OptionT<Integer> optionT = new OptionT<>(AnyM.ofMonad(Stream.of(Optional.of(10))));
System.out.println(optionT.map(num->"hello world"+num).getRun().asSequence().firstValue());
}
将打印出来
Optional[hello world10]
AnyM包装任何Monad类型。 Java不支持Higher-Kinded-Types,所以你不能将泛型放在泛型上。你可以将monad类型包装在一个公共API之后,这就是AnyM所做的事情。
如果有人对此感兴趣,独眼巨人-monad-api现在的Monad Transformers范围越来越大,受到这个问题的启发 - 感谢OP!
答案 1 :(得分:0)
github上有一个项目https://github.com/DanielGronau/highj,试图克服java缺少更高级别的类型。
但你也可以不遗余力地使用功能性编程语言和适当的更高级别的类型,例如https://github.com/Frege/frege