annotate src/main/java/fj/control/parallel/Strategy.java @ 4:19c719aba746 default tip

change getLoop return value
author tatsuki
date Mon, 20 Apr 2015 08:09:22 +0900
parents fe80c1edf1be
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
1 package fj.control.parallel;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
2
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
3 import fj.Effect;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
4 import fj.F;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
5 import fj.F2;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
6 import fj.Function;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
7 import fj.P;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
8 import fj.P1;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
9 import static fj.Function.compose;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
10 import static fj.Function.curry;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
11 import fj.data.Java;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
12 import fj.data.List;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
13 import fj.data.Array;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
14 import fj.function.Effect1;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
15
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
16 import java.util.concurrent.Callable;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
17 import java.util.concurrent.CompletionService;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
18 import java.util.concurrent.ExecutionException;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
19 import java.util.concurrent.ExecutorService;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
20 import java.util.concurrent.Future;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
21 import java.util.concurrent.FutureTask;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
22
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
23 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
24 * Functional-style parallel evaluation strategies.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
25 * A Strategy is a method of evaluating a product-1, yielding another product-1 from which the result of its evaluation
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
26 * can be retrieved at a later time.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
27 * <p/>
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
28 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
29 * @version %build.number%
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
30 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
31 public final class Strategy<A> {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
32
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
33 private final F<P1<A>, P1<A>> f;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
34
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
35 private Strategy(final F<P1<A>, P1<A>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
36 this.f = f;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
37 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
38
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
39 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
40 * Returns the functional representation of this Strategy, a function that evaluates a product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
41 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
42 * @return The function representing this strategy, which evaluates a product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
43 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
44 public F<P1<A>, P1<A>> f() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
45 return f;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
46 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
47
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
48 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
49 * Constructs a strategy from the given evaluation function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
50 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
51 * @param f The execution function for the strategy
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
52 * @return A strategy that uses the given function to evaluate product-1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
53 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
54 public static <A> Strategy<A> strategy(final F<P1<A>, P1<A>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
55 return new Strategy<A>(f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
56 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
57
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
58 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
59 * Apply the strategy to the given product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
60 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
61 * @param a A P1 to evaluate according to this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
62 * @return A P1 that yields the value from calling the given product-1.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
63 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
64 public P1<A> par(final P1<A> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
65 return f().f(a);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
66 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
67
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
68 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
69 * Promotes a function to a concurrent function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
70 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
71 * @param f A function to promote to a concurrent function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
72 * @return A function that executes concurrently when called, yielding a Future value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
73 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
74 public <B> F<B, P1<A>> concurry(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
75 return compose(f(), P1.<B, A>curry(f));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
76 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
77
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
78 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
79 * Promotes a function of arity-2 to a concurrent function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
80 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
81 * @param f The function to promote to a concurrent function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
82 * @return A function that executes concurrently when called, yielding a product-1 that returns the value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
83 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
84 public <B, C> F<B, F<C, P1<A>>> concurry(final F2<B, C, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
85 return new F<B, F<C, P1<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
86 public F<C, P1<A>> f(final B b) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
87 return concurry(curry(f).f(b));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
88 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
89 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
90 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
91
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
92 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
93 * Waits for every Future in a list to obtain a value, and collects those values in a list.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
94 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
95 * @param xs The list of Futures from which to get values.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
96 * @return A list of values extracted from the Futures in the argument list.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
97 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
98 public static <A> List<P1<A>> mergeAll(final List<Future<A>> xs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
99 return xs.map(Strategy.<A>obtain());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
100 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
101
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
102 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
103 * Evaluates a list of product-1s in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
104 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
105 * @param ps A list to evaluate in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
106 * @return A list of the values of the product-1s in the argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
107 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
108 public P1<List<A>> parList(final List<P1<A>> ps) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
109 return P1.sequence(ps.map(f()));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
110 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
111
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
112 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
113 * Maps the given function over the given list in parallel using this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
114 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
115 * @param f A function to map over the given list in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
116 * @param bs A list over which to map the given function in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
117 * @return A product-1 that returns the list with all of its elements transformed by the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
118 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
119 public <B> P1<List<A>> parMap(final F<B, A> f, final List<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
120 return P1.sequence(bs.map(concurry(f)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
121 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
122
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
123 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
124 * Maps the given function over the given array in parallel using this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
125 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
126 * @param f A function to map over the given array in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
127 * @param bs An array over which to map the given function in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
128 * @return A product-1 that returns the array with all of its elements transformed by the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
129 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
130 public <B> P1<Array<A>> parMap(final F<B, A> f, final Array<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
131 return P1.sequence(bs.map(concurry(f)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
132 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
133
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
134 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
135 * A strict version of parMap over lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
136 * Maps the given function over the given list in parallel using this strategy,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
137 * blocking the current thread until all values have been obtained.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
138 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
139 * @param f A function to map over the given list in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
140 * @param bs A list over which to map the given function in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
141 * @return A list with all of its elements transformed by the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
142 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
143 public <B> List<A> parMap1(final F<B, A> f, final List<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
144 return compose(P1.<List<A>>__1(), parMapList(f)).f(bs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
145 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
146
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
147 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
148 * A strict version of parMap over arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
149 * Maps the given function over the given arrays in parallel using this strategy,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
150 * blocking the current thread until all values have been obtained.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
151 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
152 * @param f A function to map over the given array in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
153 * @param bs An array over which to map the given function in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
154 * @return An array with all of its elements transformed by the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
155 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
156 public <B> Array<A> parMap1(final F<B, A> f, final Array<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
157 return compose(P1.<Array<A>>__1(), parMapArray(f)).f(bs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
158 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
159
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
160 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
161 * Promotes a function to a parallel function on lists using this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
162 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
163 * @param f A function to transform into a parallel function on lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
164 * @return The function transformed into a parallel function on lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
165 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
166 public <B> F<List<B>, P1<List<A>>> parMapList(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
167 return new F<List<B>, P1<List<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
168 public P1<List<A>> f(final List<B> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
169 return parMap(f, as);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
170 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
171 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
172 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
173
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
174 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
175 * First-class version of parMap on lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
176 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
177 * @return A function that promotes another function to a parallel function on lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
178 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
179 public <B> F<F<B, A>, F<List<B>, P1<List<A>>>> parMapList() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
180 return new F<F<B, A>, F<List<B>, P1<List<A>>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
181 public F<List<B>, P1<List<A>>> f(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
182 return parMapList(f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
183 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
184 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
185 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
186
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
187 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
188 * First-class version of parMap1 on lists (parallel list functor).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
189 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
190 * @return A function that promotes another function to a blocking parallel function on lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
191 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
192 public <B> F<F<B, A>, F<List<B>, List<A>>> parMapList1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
193 return new F<F<B, A>, F<List<B>, List<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
194 public F<List<B>, List<A>> f(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
195 return new F<List<B>, List<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
196 public List<A> f(final List<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
197 return parMap1(f, bs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
198 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
199 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
200 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
201 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
202 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
203
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
204 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
205 * Promotes a function to a parallel function on arrays using this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
206 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
207 * @param f A function to transform into a parallel function on arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
208 * @return The function transformed into a parallel function on arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
209 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
210 public <B> F<Array<B>, P1<Array<A>>> parMapArray(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
211 return new F<Array<B>, P1<Array<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
212 public P1<Array<A>> f(final Array<B> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
213 return parMap(f, as);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
214 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
215 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
216 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
217
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
218 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
219 * First-class version of parMap on arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
220 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
221 * @return A function that promotes another function to a parallel function on arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
222 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
223 public <B> F<F<B, A>, F<Array<B>, P1<Array<A>>>> parMapArray() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
224 return new F<F<B, A>, F<Array<B>, P1<Array<A>>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
225 public F<Array<B>, P1<Array<A>>> f(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
226 return parMapArray(f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
227 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
228 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
229 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
230
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
231 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
232 * First-class version of parMap1 on arrays (parallel array functor).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
233 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
234 * @return A function that promotes another function to a blocking parallel function on arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
235 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
236 public <B> F<F<B, A>, F<Array<B>, Array<A>>> parMapArray1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
237 return new F<F<B, A>, F<Array<B>, Array<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
238 public F<Array<B>, Array<A>> f(final F<B, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
239 return new F<Array<B>, Array<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
240 public Array<A> f(final Array<B> bs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
241 return parMap1(f, bs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
242 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
243 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
244 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
245 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
246 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
247
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
248 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
249 * Binds the given function in parallel across the given list, using the given strategy, with a final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
250 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
251 * @param s The strategy to use for parallelization.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
252 * @param f The function to bind across the given list.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
253 * @param as The list across which to bind the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
254 * @return A P1 containing the result of the parallel map operation after the final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
255 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
256 public static <A, B> P1<List<B>> parFlatMap(final Strategy<List<B>> s,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
257 final F<A, List<B>> f,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
258 final List<A> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
259 return P1.fmap(List.<B>join()).f(s.parMap(f, as));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
260 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
261
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
262 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
263 * Binds the given function in parallel across the given array, using the given strategy, with a final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
264 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
265 * @param s The strategy to use for parallelization.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
266 * @param f The function to bind across the given array.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
267 * @param as The array across which to bind the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
268 * @return A P1 containing the result of the parallel map operation after the final join.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
269 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
270 public static <A, B> P1<Array<B>> parFlatMap(final Strategy<Array<B>> s,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
271 final F<A, Array<B>> f,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
272 final Array<A> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
273 return P1.fmap(Array.<B>join()).f(s.parMap(f, as));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
274 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
275
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
276 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
277 * Sequentially evaluates chunks (sub-sequences) of a list in parallel. Splits the list into chunks,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
278 * evaluating the chunks simultaneously, but each chunk as a sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
279 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
280 * @param s The strategy to use for parallelization.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
281 * @param chunkLength The length of each sequence.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
282 * @param as The list to evaluate in parallel chunks.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
283 * @return A product-1 containing the list of results extracted from the given list of product-1s.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
284 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
285 public static <A> P1<List<A>> parListChunk(final Strategy<List<A>> s,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
286 final int chunkLength,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
287 final List<P1<A>> as) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
288 return P1.fmap(List.<A>join()).f(s.parList(as.partition(chunkLength).map(P1.<A>sequenceList())));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
289 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
290
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
291 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
292 * Zips together two lists in parallel using a given function, with this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
293 * Calls the given function once for each corresponding pair in the lists, position-wise,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
294 * passing elements from the first list to the first argument of the function, and elements from the second list
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
295 * to the second argument of the function, yielding a list of the results.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
296 * If the lists are not of the same length, the remaining elements of the longer list are ignored.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
297 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
298 * @param f The function of arity-2 with which to zip.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
299 * @param bs A list to zip with the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
300 * @param cs A list to zip with the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
301 * @return The list of the results of calling the given function on corresponding elements of the given lists.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
302 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
303 public <B, C> P1<List<A>> parZipWith(final F2<B, C, A> f, final List<B> bs, final List<C> cs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
304 return P1.sequence(bs.zipWith(cs, concurry(f)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
305 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
306
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
307 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
308 * Zips together two arrays in parallel using a given function, with this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
309 * Calls the given function once for each corresponding pair in the arrays, position-wise,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
310 * passing elements from the first array to the first argument of the function, and elements from the second array
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
311 * to the second argument of the function, yielding a array of the results.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
312 * If the arrays are not of the same length, the remaining elements of the longer array are ignored.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
313 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
314 * @param f The function of arity-2 with which to zip.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
315 * @param bs A array to zip with the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
316 * @param cs A array to zip with the given function.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
317 * @return The array of the results of calling the given function on corresponding elements of the given arrays.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
318 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
319 public <B, C> P1<Array<A>> parZipWith(final F2<B, C, A> f, final Array<B> bs, final Array<C> cs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
320 return P1.sequence(bs.zipWith(cs, concurry(f)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
321 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
322
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
323 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
324 * Lifts a given function of arity-2 so that it zips together two lists in parallel,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
325 * using this strategy, calling the function once for each corresponding pair in the lists, position-wise.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
326 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
327 * @param f The function of arity-2 with which to zip.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
328 * @return A transformation that zips two lists using the argument function, in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
329 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
330 public <B, C> F2<List<B>, List<C>, P1<List<A>>> parZipListWith(final F2<B, C, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
331 return new F2<List<B>, List<C>, P1<List<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
332 public P1<List<A>> f(final List<B> bs, final List<C> cs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
333 return parZipWith(f, bs, cs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
334 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
335 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
336 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
337
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
338 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
339 * Lifts a given function of arity-2 so that it zips together two arrays in parallel,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
340 * using this strategy, calling the function once for each corresponding pair in the arrays, position-wise.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
341 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
342 * @param f The function of arity-2 with which to zip.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
343 * @return A transformation that zips two arrays using the argument function, in parallel.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
344 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
345 public <B, C> F2<Array<B>, Array<C>, P1<Array<A>>> parZipArrayWith(final F2<B, C, A> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
346 return new F2<Array<B>, Array<C>, P1<Array<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
347 public P1<Array<A>> f(final Array<B> bs, final Array<C> cs) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
348 return parZipWith(f, bs, cs);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
349 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
350 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
351 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
352
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
353 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
354 * Returns a function which returns a product-1 which waits for the given Future to obtain a value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
355 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
356 * @return A function which, given a Future, yields a product-1 that waits for it.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
357 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
358 public static <A> F<Future<A>, P1<A>> obtain() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
359 return new F<Future<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
360 public P1<A> f(final Future<A> t) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
361 return obtain(t);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
362 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
363 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
364 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
365
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
366 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
367 * Provides a product-1 that waits for the given future to obtain a value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
368 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
369 * @param t A Future for which to wait.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
370 * @return A product-1 that waits for the given future to obtain a value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
371 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
372 public static <A> P1<A> obtain(final Future<A> t) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
373 return new P1<A>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
374 public A _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
375 try {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
376 return t.get();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
377 } catch (InterruptedException e) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
378 Thread.currentThread().interrupt();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
379 throw new Error(e);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
380 } catch (ExecutionException e) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
381 throw new Error(e);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
382 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
383 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
384 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
385 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
386
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
387 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
388 * Returns an Effect that waits for a given Future to obtain a value, discarding the value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
389 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
390 * @return An effect, which, given a Future, waits for it to obtain a value, discarding the value.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
391 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
392 public static <A> Effect1<Future<A>> discard() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
393 return new Effect1<Future<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
394 public void f(final Future<A> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
395 Strategy.<A>obtain().f(a)._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
396 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
397 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
398 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
399
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
400 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
401 * Provides a simple parallelization strategy that creates, and discards, a new thread for
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
402 * every evaluation.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
403 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
404 * @return a simple parallelization strategy that creates, and discards, a new thread for
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
405 * every evaluation.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
406 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
407 public static <A> Strategy<A> simpleThreadStrategy() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
408 return strategy(new F<P1<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
409 public P1<A> f(final P1<A> p) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
410 final FutureTask<A> t = new FutureTask<A>(Java.<A>P1_Callable().f(p));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
411 new Thread(t).start();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
412 return obtain(t);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
413 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
414 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
415 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
416
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
417 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
418 * Provides a parallelization strategy that uses an ExecutorService to control the method and
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
419 * degree of parallelism.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
420 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
421 * @param s The ExecutorService to use for scheduling evaluations.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
422 * @return A Strategy that uses the provided ExecutorService to control the method and degree
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
423 * of parallelism.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
424 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
425 public static <A> Strategy<A> executorStrategy(final ExecutorService s) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
426 return strategy(new F<P1<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
427 public P1<A> f(final P1<A> p) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
428 return obtain(s.submit(Java.<A>P1_Callable().f(p)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
429 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
430 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
431 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
432
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
433 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
434 * Provides a parallelization strategy that uses a CompletionService to control the method and
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
435 * degree of parallelism, and where each parallel task's completion is registered with the service.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
436 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
437 * @param s The CompletionService to use for scheduling evaluations and detect their completion.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
438 * @return A Strategy that uses the provided CompletionService to control the method and degree of parallelism,
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
439 * and notifies the service of task completion.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
440 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
441 public static <A> Strategy<A> completionStrategy(final CompletionService<A> s) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
442 return strategy(new F<P1<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
443 public P1<A> f(final P1<A> p) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
444 return obtain(s.submit(Java.<A>P1_Callable().f(p)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
445 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
446 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
447 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
448
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
449 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
450 * Provides a strategy that performs sequential (non-concurrent) evaluation of its argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
451 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
452 * @return A strategy that performs sequential (non-concurrent) evaluation of its argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
453 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
454 public static <A> Strategy<A> seqStrategy() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
455 return strategy(new F<P1<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
456 public P1<A> f(final P1<A> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
457 return P.p(a._1());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
458 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
459 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
460 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
461
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
462 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
463 * Provides a strategy that performs no evaluation of its argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
464 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
465 * @return A strategy that performs no evaluation of its argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
466 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
467 public static <A> Strategy<A> idStrategy() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
468 return strategy(Function.<P1<A>>identity());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
469 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
470
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
471 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
472 * Maps the given bijective transformation across this strategy (Exponential Functor pattern).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
473 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
474 * @param f A transformation from this strategy's codomain to the resulting strategy's codomain.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
475 * @param g A transformation from the resulting strategy's domain to this strategy's domain.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
476 * @return A new strategy that maps to this strategy and back again.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
477 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
478 public <B> Strategy<B> xmap(final F<P1<A>, P1<B>> f, final F<P1<B>, P1<A>> g) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
479 return strategy(compose(f, compose(f(), g)));
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
480 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
481
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
482 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
483 * Maps the given transformation across this strategy's domain (Invariant Functor pattern).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
484 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
485 * @param f A transformation from this strategy's codomain to the resulting strategy's codomain.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
486 * @return A new strategy that applies the given transformation after each application of this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
487 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
488 public Strategy<A> map(final F<P1<A>, P1<A>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
489 return xmap(f, Function.<P1<A>>identity());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
490 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
491
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
492 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
493 * Maps the given transformation across this strategy's codomain (Invariant Functor pattern).
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
494 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
495 * @param f A transformation from the resulting strategy's domain to this strategy's domain.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
496 * @return A new strategy that applies the given transformation before each application of this strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
497 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
498 public Strategy<A> comap(final F<P1<A>, P1<A>> f) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
499 return xmap(Function.<P1<A>>identity(), f);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
500 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
501
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
502 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
503 * Provides an error-handling strategy. Captures any uncaught runtime errors encountered by this strategy and applies
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
504 * the given side-effect to them.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
505 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
506 * @param e The effect that should handle errors.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
507 * @return A strategy that captures any runtime errors with a side-effect.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
508 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
509 public Strategy<A> errorStrategy(final Effect1<Error> e) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
510 return errorStrategy(this, e);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
511 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
512
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
513 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
514 * Provides an error-handling strategy. Captures any uncaught runtime errors encountered by the given strategy
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
515 * and applies the given side-effect to them.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
516 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
517 * @param s The strategy to equip with an error-handling effect.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
518 * @param e The effect that should handle errors.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
519 * @return A strategy that captures any runtime errors with a side-effect.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
520 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
521 public static <A> Strategy<A> errorStrategy(final Strategy<A> s, final Effect1<Error> e) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
522 return s.comap(new F<P1<A>, P1<A>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
523 public P1<A> f(final P1<A> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
524 return new P1<A>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
525 public A _1() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
526 try {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
527 return a._1();
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
528 } catch (Throwable t) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
529 final Error error = new Error(t);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
530 e.f(error);
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
531 throw error;
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
532 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
533 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
534 };
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
535 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
536 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
537 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
538
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
539 /**
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
540 * Provides a normalising strategy that fully evaluates its Callable argument.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
541 *
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
542 * @param s A non-normalising strategy to use for the evaluation.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
543 * @return A new strategy that fully evaluates Callables, using the given strategy.
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
544 */
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
545 public static <A> Strategy<Callable<A>> callableStrategy(final Strategy<Callable<A>> s) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
546 return s.comap(new F<P1<Callable<A>>, P1<Callable<A>>>() {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
547 public P1<Callable<A>> f(final P1<Callable<A>> a) {
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
548 return P1.curry(Callables.<A>normalise()).f(a._1());
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
549 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
550 });
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
551 }
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
552
fe80c1edf1be add getLoop
tatsuki
parents:
diff changeset
553 }