Java中的Haskell风格记忆

前端之家收集整理的这篇文章主要介绍了Java中的Haskell风格记忆前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我知道这是异端,但是我试图把这个例子从 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中甚至是有意义的,特别是关于其内在的缺乏懒惰?

解决方法

好的,这让我相信功能性编程通常是Java的一个坏主意.可以使用引用对象(其基本上实现懒惰)来解决懒惰的缺点.这是一个解决方案:
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));
}

注意,当程序运行时,它只为每个值输出一次“计算纤维”!

猜你在找的Java相关文章