Java 8 Generic of Generic for Monad Transformer
Java 8 Generic of Generic for Monad Transformer
我正在使用 "totally lazy",并且我希望在我正在编写的程序中使用 Either<String,Option<A>>
。这是将 Monad Transformer 用于 Option 的好地方(类似于 Scalaz 7 中存在的令人敬畏的转换器)。我似乎无法在 Java 8 中正确使用泛型。下面的代码是我希望它看起来像的样子(一开始)。任何有关如何将其添加到 work/compile 的建议都会很棒!!!请帮我让这个 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
您可以使用 cyclops-monad-api, there is a introductory blog post that you might find helpful here 执行此操作。我是图书馆和博客 post 的作者。
我在下面 post 编辑了您示例的有效实现(对于 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 所做的。
如果有人对 cyclops-monad-api 感兴趣,现在 Monad Transformers 的范围越来越大,受到这个问题的启发 - 谢谢 OP!
github 上有一个项目 https://github.com/DanielGronau/highj,它试图克服 java 缺乏更高种类的类型。
但是你也可以省点力气,使用具有适当高级类型的函数式编程语言,比如 https://github.com/Frege/frege
我正在使用 "totally lazy",并且我希望在我正在编写的程序中使用 Either<String,Option<A>>
。这是将 Monad Transformer 用于 Option 的好地方(类似于 Scalaz 7 中存在的令人敬畏的转换器)。我似乎无法在 Java 8 中正确使用泛型。下面的代码是我希望它看起来像的样子(一开始)。任何有关如何将其添加到 work/compile 的建议都会很棒!!!请帮我让这个 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
您可以使用 cyclops-monad-api, there is a introductory blog post that you might find helpful here 执行此操作。我是图书馆和博客 post 的作者。
我在下面 post 编辑了您示例的有效实现(对于 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 所做的。
如果有人对 cyclops-monad-api 感兴趣,现在 Monad Transformers 的范围越来越大,受到这个问题的启发 - 谢谢 OP!
github 上有一个项目 https://github.com/DanielGronau/highj,它试图克服 java 缺乏更高种类的类型。
但是你也可以省点力气,使用具有适当高级类型的函数式编程语言,比如 https://github.com/Frege/frege