Java 8 Gead of Generic for Monad Transformer

jor*_*an3 5 java generics functional-programming monad-transformers java-8

我正在使用"完全懒惰",我渴望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)));
   }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我得到以下编译器失败:

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
Run Code Online (Sandbox Code Playgroud)

Joh*_*ean 4

您可以使用cyclops-monad-api来完成此操作,这里有一篇介绍性博客文章可能会对您有所帮助。我是该库和博客文章的作者。

我在下面发布了您的示例的工作实现(对于 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());
}
Run Code Online (Sandbox Code Playgroud)

会打印出来

Optional[hello world10]
Run Code Online (Sandbox Code Playgroud)

AnyM 包装任何 Monad 类型。Java不支持Higher-Kinded-Types,所以你不能在泛型上放置泛型。不过,您可以将 monad 类型包装在通用 API 后面,这就是 AnyM 所做的。

如果有人感兴趣,受到这个问题的启发,cyclops-monad-api 现在有越来越多的Monad Transformers - 感谢 OP!