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