构建monad时Java泛型的问题
为了创建一个函数式monad,我一直在玩Java代码,但是我在使用泛型时被打动了,如果我不强制转换对象,Java编译器会给我一个编译错误(尽管泛型可以解决这个问题!) 这是用法:构建monad时Java泛型的问题,java,generics,functional-programming,monads,Java,Generics,Functional Programming,Monads,为了创建一个函数式monad,我一直在玩Java代码,但是我在使用泛型时被打动了,如果我不强制转换对象,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.funct
//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;
}
}
import java.util.function.function;
导入java.util.function.Predicate;
公共类如果{
私人T;
私有谓词;
私有If(T,谓词){
t=t;
this.predicate=谓词;
}
公共静态If of(T,谓词){
返回新的If(t,谓词);
}
公共(如果适用)(功能){
if(谓词!=null&&predicate.test(t)){
返回新的If(function.apply(t),null);
}
返回If.of(this.t,null);
}
公共部门得不到{
返回t;
}
}
直接的问题是方法的的返回类型是原始的:
public static<T> If of(T t, Predicate predicate) {
那么您的签名可以是:
public static<T> If<T> of(T t, Predicate<T> predicate) {
公共静态If of(T,谓词){
如果希望API更加灵活,请添加通配符:
public static<T> If<T> of(T t, Predicate<? super T> predicate) {
publicstaticif of(T,PredicateAndy Turner的回答解释了当前代码无法编译的直接原因,但您的monad似乎有一个更根本的问题——它不是很有用
根据您的说法,如果条件为true,则对apply
的第一次调用应返回包装在monad中的转换对象,如果条件为false,则应返回包装在monad中的原始对象。但是,由于您将null
作为这两种情况的条件,因此对apply
的任何后续调用都将导致要到达的第二个返回
,因此总是返回第一次调用应用
的结果
事实上,既不能返回原始对象,也不能返回转换后的对象(无论如何,这不是一种有用且类型安全的方式)。要安全地进行键入,您需要一个或(假设存在这样的类型).但是要从或中提取值,仍然需要一个if语句,这与if
类的目的背道而驰
显然,这只是一个练习编写monad的练习。在这种情况下,我建议您选择另一个monad来实现,例如或。我也建议您先看看这个。公共静态If of(T,谓词谓词){
--返回类型是原始的。我想它应该是谓词
左右。如果包含编译器的错误消息,将使用原始类型的问题放在一边,那会很有帮助。这个monad应该做什么?If.of(1,x->x>2)。apply(Integer::toString).get()会做什么
return?换句话说,当条件为false时会发生什么?您是否期望null
?如果条件为false,它将返回此值。例如,它就像mapIf,它将存在于可选的monad中。它仅在验证谓词时应用转换。并且,否,get
无法返回原始对象或转换对象,因为它们可能是不同的类型。原始对象的类型是T
,而转换对象的类型是R
。您可以在这里使用或单子,但如果的话,这种类型会破坏的目的,对吗?因为您仍然必须检查返回的是哪一个ed.你想用这个If
monad实现什么?如果这只是monad的一个练习,那么还有很多其他monad可以编写。非常有趣的建议,我已经尝试过了,但在apply()的最后一次返回中方法它给了我编译错误,因为它返回的是If而不是If。如何解决这个问题?谢谢@Sweeper not null而是this。这意味着返回monad本身。@AlexMawashi哦,对了。在这种情况下,你根本不需要R
:你必须返回If
。
public static<T> If<T> of(T t, Predicate<T> predicate) {
public static<T> If<T> of(T t, Predicate<? super T> predicate) {
public <R> If<R> apply(Function<? super T, ? extends R> function) {