Mercurial > hg > Members > tatsuki > functionaljava-master > core
view src/main/java/fj/test/Variant.java @ 0:fe80c1edf1be
add getLoop
author | tatsuki |
---|---|
date | Fri, 20 Mar 2015 21:04:03 +0900 |
parents | |
children |
line wrap: on
line source
package fj.test; import fj.F; import static fj.test.Gen.gen; import java.util.HashMap; /** * A memoised generator variant. Stores generators that have already been computed for the given arguments. * * @version %build.number% */ public final class Variant { private static final HashMap<LongGen, Gen<?>> variantMemo = new HashMap<LongGen, Gen<?>>(); private static final class LongGen { private final long n; private final Gen<?> gen; LongGen(final long n, final Gen<?> gen) { this.n = n; this.gen = gen; } public boolean equals(final Object o) { return o != null && o.getClass() == LongGen.class && n == ((LongGen)o).n && gen == ((LongGen)o).gen; } public int hashCode() { final int p = 419; int result = 239; result = p * result + (int) (n ^ n >>> 32); result = p * result + gen.hashCode(); return result; } } private Variant() { throw new UnsupportedOperationException(); } /** * Produces a generator that is independent of the given generator using the given value. * * @param n The value to produce the new generator from. * @param g The generator to produce the new generator from. * @return A generator that is independent of the given generator using the given value. */ public static <A> Gen<A> variant(final long n, final Gen<A> g) { final LongGen p = new LongGen(n, g); final Gen<?> gx = variantMemo.get(p); if(gx == null) { final Gen<A> t = gen(new F<Integer, F<Rand, A>>() { public F<Rand, A> f(final Integer i) { return new F<Rand, A>() { public A f(final Rand r) { return g.gen(i, r.reseed(n)); } }; } }); variantMemo.put(p, t); return t; } else return gen(new F<Integer, F<Rand, A>>() { public F<Rand, A> f(final Integer i) { return new F<Rand, A>() { @SuppressWarnings({"unchecked"}) public A f(final Rand r) { return (A)gx.gen(i, r); } }; } }); } /** * A curried version of {@link #variant(long, Gen)}. * * @param n The value to produce the new generator from. * @return A curried version of {@link #variant(long, Gen)}. */ public static <A> F<Gen<A>, Gen<A>> variant(final long n) { return new F<Gen<A>, Gen<A>>() { public Gen<A> f(final Gen<A> g) { return variant(n, g); } }; } }