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 }