好的,所以我在 java 中实现了 state monad。但是,我似乎无法让泛型正常工作。我有下面的代码,并试图避免指出的情况。
public interface Monad<M, A>
{
<B, R extends Monad<M, B>> R bind(Function<? super A, R> p_function);
}
public class State<S, A> implements Monad<State<S, ?>, A>
{
private Function<S, Pair<S, A>> m_function;
public State(Function<S, Pair<S, A>> p_function)
{
m_function = p_function;
}
public final Pair<S, A> run(S p_state)
{
return m_function.apply(p_state);
}
@Override
public <B, R extends Monad<State<S, ?>, B>> R bind(
final Function<? super A, R> p_function)
{
// I want to avoid the cast to R here
return (R) new State<S, B>((S state) -> {
Pair<S, A> run = run(state);
// And this cast, but they seem related
State<S, B> applied = (State<S, B>) p_function.apply(run.second());
return applied.run(run.first());
});
}
}
注意:我知道如果我可以避免bind
to
<B> Monad<M, B> bind(Function<? super A, ? extends Monad<M, B>> p_function);
The cast 的签名。但是,这会导致以下方法中的编译错误
public static <A, B, C, M, MB extends Monad<M, B>, MC extends Monad<M, C>>
Function<A, MC> compose(
Function<? super A, MB> p_first, Function<? super B, MC> p_second)
{
// have to use an anonymous class here, because using a closure causes a
// runtime error with the beta version of JDK 8
return new Function<A, MC>() {
@Override
public MC apply(A arg) {
MB monadOfB = p_first.apply(arg);
return monadOfB.<C> bind(p_second); // <-- type error here
}
};
}
compose
现在,我也尝试以类似的方式
更改签名。即,而不是MB extends Monad<M, B>
我在使用Monad<M, B>
MB 的地方使用,对于 MC 也是如此。这使得compose
方法编译。compose
但是, ie的调用者无法正确推断出返回类型
Function<String, State<Integer, String>> left = ...;
Function<String, State<Integer, String>> right = ...;
Function<String, State<Integer, String>> composed = Monad.compose(left, right);
如果没有在方法调用上指定类型,则不起作用,而在它之前。
我如何让所有这些泛型很好地结合在一起?