Ale*_*shi 2 java generics monads functional-programming
我正在玩 Java 代码以创建一个函数式风格的 monad,但是我在使用泛型时感到震惊,如果我不强制转换我的对象,Java 编译器会给我一个编译错误(尽管泛型可以解决这个问题!)
这是用法:
//COMPILATION ERROR! It requires a cast to String
String message = If.of("Hi", s->s!=null).apply(s->s+" guys!").get();
Run Code Online (Sandbox Code Playgroud)
允许:
这是我的单子:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
直接的问题是该方法的返回类型of是原始的:
public static<T> If of(T t, Predicate predicate) {
Run Code Online (Sandbox Code Playgroud)
你大概需要它是这样的:
public static<T> If<T, Something> of(T t, Predicate<T> predicate) {
Run Code Online (Sandbox Code Playgroud)
我建议你不要真的想把 烘焙R成If's 类型。如果您改为在方法上声明它,则您可以灵活地将apply其设置为您需要的任何类型:
public class If<T> {
// ...
public <R> If<R> apply(Function<T, R> function) {
if(predicate!=null && predicate.test(t)){
return new If<>(function.apply(t), null);
}
return If.of(this.t, null);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
那么你的of签名可以是简单的:
public static<T> If<T> of(T t, Predicate<T> predicate) {
Run Code Online (Sandbox Code Playgroud)
如果您希望 API 更加灵活,请添加通配符:
public static<T> If<T> of(T t, Predicate<? super T> predicate) {
Run Code Online (Sandbox Code Playgroud)
和
public <R> If<R> apply(Function<? super T, ? extends R> function) {
Run Code Online (Sandbox Code Playgroud)