Я знаю, что это ересь, но я попытался перевести примеры из http://www.haskell.org/haskellwiki/Memoization в Java. До сих пор я:
public abstract class F<A,B> {
public abstract B f(A a);
}
...
public static <A, B> F<A, B> memoize(final F<A, B> fn) {
return new F<A, B>() {
private final Map<A, B> map = new HashMap<A, B>();
public B f(A a) {
B b = map.get(a);
if (b == null) {
b = fn.f(a);
map.put(a, b);
}
return b;
}
};
}
//usage:
private class Cell<X> {
public X value = null;
}
...
final Cell<F<Integer, BigInteger>> fibCell = new Cell<F<Integer, BigInteger>>();
fibCell.value = memoize(new F<Integer, BigInteger>() {
public BigInteger f(Integer a) {
return a <= 1 ? BigInteger.valueOf(a) : fibCell.value.f(a - 1).add(fibCell.value.f(a - 2));
}
});
System.out.println(fibCell.value.f(1000));
Это прекрасно работает. Теперь я попытался реализовать комбинатор memoFix
, определенный как
memoFix :: ((a -> b) -> (a -> b)) -> a -> b
memoFix f =
let mf = memoize (f mf) in mf
Но я застрял. Разве это даже имеет смысл в Java, особенно в отношении присущего ему ленивости?