【发布时间】:2020-05-12 15:04:37
【问题描述】:
我正在使用 Java 代码来创建一个函数式风格的 monad,但是我在使用泛型时感到震惊,如果我不强制转换我的对象,Java 编译器会给我一个编译错误(尽管泛型可以解决这个问题!)
这是用法:
//COMPILATION ERROR! It requires a cast to String
String message = If.of("Hi", s->s!=null).apply(s->s+" guys!").get();
允许:
这是我的单子:
import java.util.function.Function;
import java.util.function.Predicate;
public class If<T, R> {
private T t;
private Predicate predicate;
private If(T t, Predicate predicate) {
this.t = t;
this.predicate = predicate;
}
public static<T> If of(T t, Predicate predicate) {
return new If(t, predicate);
}
public If<R,R> apply(Function<T, R> function) {
if(predicate!=null && predicate.test(t)){
return new If<R, R>(function.apply(t), null);
}
return If.of(this.t, null);
}
public T get() {
return t;
}
}
【问题讨论】:
-
public static<T> If of(T t, Predicate predicate) {-- 返回类型为 raw。 -
我猜应该是
Predicate<T>左右。包含来自编译器的错误消息会很有帮助... -
抛开使用原始类型的问题。这个单子应该做什么?
If.of(1, x -> x > 2).apply(Integer::toString).get()会返回什么?换句话说,当条件为假时会发生什么?你期待null吗? -
如果条件为假,则返回 this。例如,它就像一个 mapIf 它本来存在于 Optional monad 中。仅当 Predicate 被验证时才应用转换。
-
不,
get无法返回原始对象或转换后的对象,因为它们可能是不同的类型。原始对象的类型为T,而转换后的对象的类型为R。你可以在这里使用Eithermonad,但这违背了If的目的,对吧?因为您仍然需要检查返回的是哪一个。你实际上想用这个Ifmonad 完成什么?如果这只是 monad 的练习,那么您可以编写许多其他 monad。
标签: java generics functional-programming monads