Haskell style memory in Java

I know it's heresy, but I'm trying to take this example from http://www.haskell.org/haskellwiki/Memoization Translate into Java So far, I have:

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));

Now I'm trying to implement the memofix combiner defined as

memoFix :: ((a -> b) -> (a -> b)) -> a -> b
memoFix f =
   let mf = memoize (f mf) in mf

But am I stuck, which is even meaningful in Java, especially about its inherent lack of laziness?

Solution

Well, this leads me to believe that functional programming is usually a bad idea for Java You can use reference objects, which basically implement laziness, to solve the disadvantage of laziness This is a solution:

public static class FunctionRef<A,B> {
    private F<A,B> func;
    public void set(F<A,B> f) { func = f; }
    public F<A,B> get() { return func; }
}

public static class Pair<A,B> {
    public final A first; public final B second;
    public Pair(A a,B b) {
        this.first = a; this.second = b;
    }
}

public static <A,B> memoFix(final F<Pair<FunctionRef<A,B>,A>,B> func) {
    final FunctionRef<A,B> y = new FunctionRef<A,B>();
    y.set(
        memoize(new F<A,B>() {
            @Override
            public B f(A a) {
                return func.f(new Pair<FunctionRef<A,A>(y,a));
            }
        })
    );
    return y.get();
}


//Test that it works
public static void main(String[] args) {
    F<Pair<FunctionRef<Integer,Integer>,Integer> fib = new F<Pair<FunctionRef<Integer,Integer>() {
        @Override
        public Integer f(Pair<FunctionRef<Integer,Integer> a) {
            int value = a.second;
            System.out.println("computing fib of " + value);
            if (value == 0) return 0;
            if (value == 1) return 1;
            return a.first.get().f(value - 2) + a.first.get().f(value - 1);
        }
    };

    F<Integer,Integer> memoized = memoFix(fib);
    System.out.println(memoized.f(10));
}

Note that when the program runs, it only outputs "calculated fiber" once for each value!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>