001    package fj.control.parallel;
002    
003    import fj.F;
004    import fj.F2;
005    import fj.Function;
006    import static fj.Function.curry;
007    import fj.P1;
008    import fj.data.Either;
009    import static fj.data.Either.left;
010    import static fj.data.Either.right;
011    import fj.data.List;
012    import fj.data.Option;
013    import static fj.data.Option.none;
014    import static fj.data.Option.some;
015    
016    import java.util.concurrent.Callable;
017    
018    /**
019     * Monadic functions and conversion methods for java.util.concurrent.Callable.
020     *
021     * @version %build.number%<br>
022     *          <ul>
023     *          <li>$LastChangedRevision: 5 $</li>
024     *          <li>$LastChangedDate: 2008-12-06 16:49:43 +1000 (Sat, 06 Dec 2008) $</li>
025     *          <li>Author: runar</li>
026     *          </ul>
027     */
028    public final class Callables {
029      private Callables() {
030      }
031    
032      /**
033       * Returns a callable that completely preserves the argument. The unit function for Callables.
034       *
035       * @param a A value to preserve in a Callable
036       * @return A Callable that yields the argument when called.
037       */
038      public static <A> Callable<A> callable(final A a) {
039        return new Callable<A>() {
040          public A call() throws Exception {
041            return a;
042          }
043        };
044      }
045    
046      /**
047       * Returns a callable that throws the given exception. The unit function for Callables.
048       *
049       * @param e The exception to throw when the Callable is called.
050       * @return A callable that always throws the given exception.
051       */
052      public static <A> Callable<A> callable(final Exception e) {
053        return new Callable<A>() {
054          public A call() throws Exception {
055            throw e;
056          }
057        };
058      }
059    
060      /**
061       * Provides a transformation from a value to a Callable that completely preserves that value.
062       *
063       * @return A function from a value to a Callable that completely preserves that value.
064       */
065      public static <A> F<A, Callable<A>> callable() {
066        return new F<A, Callable<A>>() {
067          public Callable<A> f(final A a) {
068            return callable(a);
069          }
070        };
071      }
072    
073      /**
074       * Wraps a given function's return value in a Callable.
075       * The Kleisli arrow for Callables.
076       *
077       * @param f The function whose return value to wrap in a Callable.
078       * @return The equivalent function whose return value is wrapped in a Callable.
079       */
080      public static <A, B> F<A, Callable<B>> callable(final F<A, B> f) {
081        return new F<A, Callable<B>>() {
082          public Callable<B> f(final A a) {
083            return new Callable<B>() {
084              public B call() {
085                return f.f(a);
086              }
087            };
088          }
089        };
090      }
091    
092      /**
093       * Provides a transformation from a function to a Callable-valued function that is equivalent to it.
094       * The first-class Kleisli arrow for Callables.
095       *
096       * @return A transformation from a function to the equivalent Callable-valued function.
097       */
098      public static <A, B> F<F<A, B>, F<A, Callable<B>>> arrow() {
099        return new F<F<A, B>, F<A, Callable<B>>>() {
100          public F<A, Callable<B>> f(final F<A, B> f) {
101            return callable(f);
102          }
103        };
104      }
105    
106      /**
107       * Binds the given function to the value in a Callable with a final join.
108       *
109       * @param a A value in a Callable to which to apply a function.
110       * @param f A function to apply to the value in a Callable.
111       * @return The result of applying the function in the second argument to the value of the Callable in the first.
112       */
113      public static <A, B> Callable<B> bind(final Callable<A> a, final F<A, Callable<B>> f) {
114        return new Callable<B>() {
115          public B call() throws Exception {
116            return f.f(a.call()).call();
117          }
118        };
119      }
120    
121      /**
122       * Lifts any function to a function on Callables.
123       *
124       * @param f A function to lift to a function on Callables.
125       * @return That function lifted to a function on Callables.
126       */
127      public static <A, B> F<Callable<A>, Callable<B>> fmap(final F<A, B> f) {
128        return new F<Callable<A>, Callable<B>>() {
129          public Callable<B> f(final Callable<A> a) {
130            return bind(a, callable(f));
131          }
132        };
133      }
134    
135      /**
136       * Performs function application within a callable (applicative functor pattern).
137       *
138       * @param ca The callable to which to apply a function.
139       * @param cf The callable function to apply.
140       * @return A new callable after applying the given callable function to the first argument.
141       */
142      public static <A, B> Callable<B> apply(final Callable<A> ca, final Callable<F<A, B>> cf) {
143        return bind(cf, new F<F<A, B>, Callable<B>>() {
144          public Callable<B> f(final F<A, B> f) {
145            return fmap(f).f(ca);
146          }
147        });
148      }
149    
150      /**
151       * Binds the given function to the values in the given callables with a final join.
152       *
153       * @param ca A given callable to bind the given function with.
154       * @param cb A given callable to bind the given function with.
155       * @param f  The function to apply to the values in the given callables.
156       * @return A new callable after performing the map, then final join.
157       */
158      public static <A, B, C> Callable<C> bind(final Callable<A> ca, final Callable<B> cb, final F<A, F<B, C>> f) {
159        return apply(cb, fmap(f).f(ca));
160      }
161    
162      /**
163       * Joins a Callable of a Callable with a bind operation.
164       *
165       * @param a The Callable of a Callable to join.
166       * @return A new Callable that is the join of the given Callable.
167       */
168      public static <A> Callable<A> join(final Callable<Callable<A>> a) {
169        return bind(a, Function.<Callable<A>>identity());
170      }
171    
172      /**
173       * Promotes a function of arity-2 to a function on callables.
174       *
175       * @param f The function to promote.
176       * @return A function of arity-2 promoted to map over callables.
177       */
178      public static <A, B, C> F<Callable<A>, F<Callable<B>, Callable<C>>> liftM2(final F<A, F<B, C>> f) {
179        return curry(new F2<Callable<A>, Callable<B>, Callable<C>>() {
180          public Callable<C> f(final Callable<A> ca, final Callable<B> cb) {
181            return bind(ca, cb, f);
182          }
183        });
184      }
185    
186      /**
187       * Turns a List of Callables into a single Callable of a List.
188       *
189       * @param as The list of callables to transform.
190       * @return A single callable for the given List.
191       */
192      public static <A> Callable<List<A>> sequence(final List<Callable<A>> as) {
193        return as.foldRight(Callables.<A, List<A>,
194            List<A>>liftM2(List.<A>cons()), callable(List.<A>nil()));
195      }
196    
197      /**
198       * A first-class version of the sequence method.
199       *
200       * @return A function from a List of Callables to a single Callable of a List.
201       */
202      public static <A> F<List<Callable<A>>, Callable<List<A>>> sequence_() {
203        return new F<List<Callable<A>>, Callable<List<A>>>() {
204          public Callable<List<A>> f(final List<Callable<A>> as) {
205            return sequence(as);
206          }
207        };
208      }
209    
210      /**
211       * Turns the given Callable into an optional value.
212       *
213       * @param a The callable to convert to an optional value.
214       * @return An optional value that yields the value in the Callable, or None if the Callable fails.
215       */
216      public static <A> P1<Option<A>> option(final Callable<A> a) {
217        return new P1<Option<A>>() {
218          @SuppressWarnings({"UnusedCatchParameter"})
219          public Option<A> _1() {
220            try {
221              return some(a.call());
222            } catch (Exception e) {
223              return none();
224            }
225          }
226        };
227      }
228    
229      /**
230       * Returns a transformation from a Callable to an optional value.
231       *
232       * @return a function that turns a Callable into an optional value.
233       */
234      public static <A> F<Callable<A>, P1<Option<A>>> option() {
235        return new F<Callable<A>, P1<Option<A>>>() {
236          public P1<Option<A>> f(final Callable<A> a) {
237            return option(a);
238          }
239        };
240      }
241    
242      /**
243       * Turns the given Callable into either an exception or the value in the Callable.
244       *
245       * @param a The callable to convert to an Either value.
246       * @return Either the value in the given Callable, or the Exception with which the Callable fails.
247       */
248      public static <A> P1<Either<Exception, A>> either(final Callable<A> a) {
249        return new P1<Either<Exception, A>>() {
250          public Either<Exception, A> _1() {
251            try {
252              return right(a.call());
253            } catch (Exception e) {
254              return left(e);
255            }
256          }
257        };
258      }
259    
260      /**
261       * Returns a transformation from a Callable to an Either.
262       *
263       * @return a function that turns a Callable into an Either.
264       */
265      public static <A> F<Callable<A>, P1<Either<Exception, A>>> either() {
266        return new F<Callable<A>, P1<Either<Exception, A>>>() {
267          public P1<Either<Exception, A>> f(final Callable<A> a) {
268            return either(a);
269          }
270        };
271      }
272    
273      /**
274       * Turns a given Either value into the equivalent Callable.
275       *
276       * @param e Either an exception or a value to wrap in a Callable
277       * @return A Callable equivalent to the given Either value.
278       */
279      public static <A> Callable<A> fromEither(final P1<Either<Exception, A>> e) {
280        return new Callable<A>() {
281          public A call() throws Exception {
282            final Either<Exception, A> e1 = e._1();
283            if (e1.isLeft())
284              throw e1.left().value();
285            else
286              return e1.right().value();
287          }
288        };
289      }
290    
291      /**
292       * Returns a transformation from an Either to a Callable.
293       *
294       * @return a function that turns an Either into a Callable.
295       */
296      public static <A> F<P1<Either<Exception, A>>, Callable<A>> fromEither() {
297        return new F<P1<Either<Exception, A>>, Callable<A>>() {
298          public Callable<A> f(final P1<Either<Exception, A>> e) {
299            return fromEither(e);
300          }
301        };
302      }
303    
304      /**
305       * Turns an optional value into a Callable.
306       *
307       * @param o An optional value to turn into a Callable.
308       * @return A Callable that yields some value or throws an exception in the case of no value.
309       */
310      public static <A> Callable<A> fromOption(final P1<Option<A>> o) {
311        return new Callable<A>() {
312          public A call() throws Exception {
313            final Option<A> o1 = o._1();
314            if (o1.isSome())
315              return o1.some();
316            else
317              throw new Exception("No value.");
318          }
319        };
320      }
321    
322      /**
323       * Returns a transformation from an optional value to a Callable
324       *
325       * @return A function that turns an optional value into a Callable that yields some value
326       *         or throws an exception in the case of no value.
327       */
328      public static <A> F<P1<Option<A>>, Callable<A>> fromOption() {
329        return new F<P1<Option<A>>, Callable<A>>() {
330          public Callable<A> f(final P1<Option<A>> o) {
331            return fromOption(o);
332          }
333        };
334      }
335    
336      /**
337       * Normalises the given Callable by calling it and wrapping the result in a new Callable.
338       * If the given Callable throws an Exception, the resulting Callable will throw that same Exception.
339       *
340       * @param a The callable to evaluate.
341       * @return A normalised callable that just returns the result of calling the given callable.
342       */
343      public static <A> Callable<A> normalise(final Callable<A> a) {
344        try {
345          return callable(a.call());
346        } catch (Exception e) {
347          return callable(e);
348        }
349      }
350    
351      /**
352       * A first-class version of the normalise function.
353       *
354       * @return A function that normalises the given Callable by calling it and wrapping the result in a new Callable.
355       */
356      public static <A> F<Callable<A>, Callable<A>> normalise() {
357        return new F<Callable<A>, Callable<A>>() {
358          public Callable<A> f(final Callable<A> a) {
359            return normalise(a);
360          }
361        };
362      }
363    
364    }