forked from functionaljava/functionaljava
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVariant.java
More file actions
73 lines (62 loc) · 1.94 KB
/
Variant.java
File metadata and controls
73 lines (62 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
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<>();
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.
*/
@SuppressWarnings("unchecked")
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(i -> r -> g.gen(i, r.reseed(n)));
variantMemo.put(p, t);
return t;
} else return gen(i -> r -> (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 g -> variant(n, g);
}
}