在 Java 8 中实现 Monad
Implementing Monads in Java 8
我正在尝试在 this article 之后的 Java 8 中实现一个 Monad 接口,但是我遇到了以下编译错误
发现 2 个错误:
File:FunctorsMonads.java [line: 36]
Error: FOptional is not abstract and does not override abstract method flatMap(java.util.function.Function>) in Monad
File:FunctorsMonads.java [line: 50]
Error: name clash: flatMap(java.util.function.Function>) in FOptional and flatMap(java.util.function.Function) in Monad have the same erasure, yet neither overrides the other
Functor
界面工作正常。非常感谢任何帮助。
代码如下:
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 + ">";
}
}
编辑:
我在 main 方法中添加了以下几行作为实现正确性的试金石:
FOptional<Integer> num2 = str.flatMap(FunctorsMonads::tryParse);
System.out.println(num2);
实现的方法 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);
}
它们都定义了 return 新泛型类型的方法:Monad
和 M
以及 Functor
和 F
并使用新引入的泛型输入 R
.
您无法在 Java 中实现完全类型安全的 Monad 接口。 flatmap 的正确签名类似于 <R> M<R> flatMap(Function<T, M<R>> f)
,但这在 Java 中无法表达。此 M<R>
表达式称为 higher-kinded type.
我正在尝试在 this article 之后的 Java 8 中实现一个 Monad 接口,但是我遇到了以下编译错误
发现 2 个错误:
File:FunctorsMonads.java [line: 36]
Error: FOptional is not abstract and does not override abstract method flatMap(java.util.function.Function>) in Monad
File:FunctorsMonads.java [line: 50]
Error: name clash: flatMap(java.util.function.Function>) in FOptional and flatMap(java.util.function.Function) in Monad have the same erasure, yet neither overrides the other
Functor
界面工作正常。非常感谢任何帮助。
代码如下:
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 + ">";
}
}
编辑:
我在 main 方法中添加了以下几行作为实现正确性的试金石:
FOptional<Integer> num2 = str.flatMap(FunctorsMonads::tryParse);
System.out.println(num2);
实现的方法 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);
}
它们都定义了 return 新泛型类型的方法:Monad
和 M
以及 Functor
和 F
并使用新引入的泛型输入 R
.
您无法在 Java 中实现完全类型安全的 Monad 接口。 flatmap 的正确签名类似于 <R> M<R> flatMap(Function<T, M<R>> f)
,但这在 Java 中无法表达。此 M<R>
表达式称为 higher-kinded type.