在Java 8中实现Monad

时间:2019-01-03 16:28:34

标签: java generics java-8 functional-programming monads

我正在this article之后尝试在Java 8中实现Monad接口,但是出现以下编译错误


发现2个错误:

  •   

    File:FunctorsMonads.java [line:36]

         

    错误:FOptional不是抽象的,并且不会覆盖Monad中的抽象方法flatMap(java.util.function.Function>)

  •   

    File:FunctorsMonads.java [line:50]

         

    错误:名称冲突:FOptional中的flatMap(java.util.function.Function>)和Monad中的flatMap(java.util.function.Function)具有相同的擦除,但是都不能覆盖另一个


command not found界面可以正常工作。非常感谢您的帮助。

代码如下:

Functor

修改:
我在main方法中添加了以下几行,作为对实现的正确性的试金石:
import java.util.function.Function; public class FunctorsMonads { public static void main(String[] args) { System.out.println(tryParse("47")); System.out.println(tryParse("a")); FOptional<String> str = FOptional.of("47"); System.out.println(str); FOptional<FOptional<Integer>> num = str.map(FunctorsMonads::tryParse); System.out.println(num); FOptional<Integer> num2 = str.flatMap(FunctorsMonads::tryParse); System.out.println(num2); } static FOptional<Integer> tryParse(String s){ try { final int i = Integer.parseInt(s); return FOptional.of(i); } catch (NumberFormatException e) { return FOptional.empty(); } } } interface Functor<T, F extends Functor<?, ?>> { <R> F map(Function<T, R> f); } interface Monad<T, M extends Monad<?, ?>> extends Functor<T, M> { M flatMap(Function<T, M> f); } //class FOptional<T> implements Functor<T, FOptional<?>> class FOptional<T> implements Monad<T, FOptional<?>> { private final T valueOrNull; private FOptional(T valueOrNull) { this.valueOrNull = valueOrNull; } public <R> FOptional<R> map(Function<T, R> f) { if (valueOrNull == null) return empty(); else return of(f.apply(valueOrNull)); } public <R> FOptional<R> flatMap(Function<T, FOptional<R>> f) { if (valueOrNull == null) return empty(); else return f.apply(valueOrNull); } public static <T> FOptional<T> of(T a) { return new FOptional<T>(a); } public static <T> FOptional<T> empty() { return new FOptional<T>(null); } @Override public String toString() { return getClass().getName() + "<" + valueOrNull + ">"; } }

2 个答案:

答案 0 :(得分:6)

您不能在Java中实现完全类型安全的Monad接口。平面图的正确签名类似于<R> M<R> flatMap(Function<T, M<R>> f),但这在Java中无法表达。此M<R>表达式称为higher-kinded type

答案 1 :(得分:1)

已实现的方法FOptional::flatMap与接口Monad中的定义不匹配。

您需要做的就是修改界面Monad本身:

interface Monad<T, M extends Monad<?, ?>> extends Functor<T, M> {

    <R> M flatMap(Function<T, FOptional<R>> f);
}

据我从功能上了解,两个接口的设计应具有相同的精神。将新界面与Functor界面进行比较:

interface Functor<T, F extends Functor<?, ?>> {

    <R> F map(Function<T, R> f);
}

这两个方法都定义了返回新通用类型的方法:Monad的{​​{1}}和M的{​​{1}}并使用新引入的通用类型Functor