/** * Applies this function partially to one argument. * * @param t1 argument 1 * @return a partial application of this function */ default CheckedFunction2<T2, T3, R> apply(T1 t1) { return (T2 t2, T3 t3) -> apply(t1, t2, t3); }
/** * Returns a tupled version of this function. * * @return a tupled function equivalent to this. */ default CheckedFunction1<Tuple3<T1, T2, T3>, R> tupled() { return t -> apply(t._1, t._2, t._3); }
/** * Returns a reversed version of this function. This may be useful in a recursive context. * * @return a reversed function equivalent to this. */ default CheckedFunction3<T3, T2, T1, R> reversed() { return (t3, t2, t1) -> apply(t1, t2, t3); }
/** * Applies this function partially to two arguments. * * @param t1 argument 1 * @param t2 argument 2 * @return a partial application of this function */ default CheckedFunction1<T3, R> apply(T1 t1, T2 t2) { return (T3 t3) -> apply(t1, t2, t3); }
/** * Returns a curried version of this function. * * @return a curried function equivalent to this. */ default Function1<T1, Function1<T2, CheckedFunction1<T3, R>>> curried() { return t1 -> t2 -> t3 -> apply(t1, t2, t3); }
/** * Lifts the given {@code partialFunction} into a total function that returns an {@code Try} result. * * @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing) * @param <R> return type * @param <T1> 1st argument * @param <T2> 2nd argument * @param <T3> 3rd argument * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Success(result)} * if the function is defined for the given arguments, and {@code Failure(throwable)} otherwise. */ static <T1, T2, T3, R> Function3<T1, T2, T3, Try<R>> liftTry(CheckedFunction3<? super T1, ? super T2, ? super T3, ? extends R> partialFunction) { return (t1, t2, t3) -> Try.of(() -> partialFunction.apply(t1, t2, t3)); }
/** * Returns a composed function that first applies this CheckedFunction3 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction3<T1, T2, T3, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3) -> after.apply(apply(t1, t2, t3)); }
/** * Returns an unchecked function that will <em>sneaky throw</em> if an exceptions occurs when applying the function. * * @return a new Function3 that throws a {@code Throwable}. */ default Function3<T1, T2, T3, R> unchecked() { return (t1, t2, t3) -> { try { return apply(t1, t2, t3); } catch(Throwable t) { return sneakyThrow(t); } }; }
/** * Return a composed function that first applies this CheckedFunction3 to the given arguments and in case of throwable * try to get value from {@code recover} function with same arguments and throwable information. * * @param recover the function applied in case of throwable * @return a function composed of this and recover * @throws NullPointerException if recover is null */ default Function3<T1, T2, T3, R> recover(Function<? super Throwable, ? extends Function3<? super T1, ? super T2, ? super T3, ? extends R>> recover) { Objects.requireNonNull(recover, "recover is null"); return (t1, t2, t3) -> { try { return this.apply(t1, t2, t3); } catch (Throwable throwable) { final Function3<? super T1, ? super T2, ? super T3, ? extends R> func = recover.apply(throwable); Objects.requireNonNull(func, () -> "recover return null for " + throwable.getClass() + ": " + throwable.getMessage()); return func.apply(t1, t2, t3); } }; }
/** * Returns a checkable property that checks values of the 3 variables of this {@code ForAll} quantor. * * @param predicate A 3-ary predicate * @return a new {@code Property3} of 3 variables. */ public Property3<T1, T2, T3> suchThat(CheckedFunction3<T1, T2, T3, Boolean> predicate) { final CheckedFunction3<T1, T2, T3, Condition> proposition = (t1, t2, t3) -> new Condition(true, predicate.apply(t1, t2, t3)); return new Property3<>(name, a1, a2, a3, proposition); } }
/** * Returns an implication which composes this Property as pre-condition and a given post-condition. * * @param postcondition The postcondition of this implication * @return A new Checkable implication */ public Checkable implies(CheckedFunction3<T1, T2, T3, Boolean> postcondition) { final CheckedFunction3<T1, T2, T3, Condition> implication = (t1, t2, t3) -> { final Condition precondition = predicate.apply(t1, t2, t3); if (precondition.isFalse()) { return Condition.EX_FALSO_QUODLIBET; } else { return new Condition(true, postcondition.apply(t1, t2, t3)); } }; return new Property3<>(name, a1, a2, a3, implication); }
/** * Lifts the given {@code partialFunction} into a total function that returns an {@code Option} result. * * @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing) * @param <R> return type * @param <T1> 1st argument * @param <T2> 2nd argument * @param <T3> 3rd argument * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Some(result)} * if the function is defined for the given arguments, and {@code None} otherwise. */ @SuppressWarnings("RedundantTypeArguments") static <T1, T2, T3, R> Function3<T1, T2, T3, Option<R>> lift(CheckedFunction3<? super T1, ? super T2, ? super T3, ? extends R> partialFunction) { return (t1, t2, t3) -> Try.<R>of(() -> partialFunction.apply(t1, t2, t3)).toOption(); }
/** * Wraps the result of a computation that may fail in a {@code Try}. * * @param f A computation that takes three {@code AutoClosable} resources. * @param <R> Result type of the computation. * @return A new {@code Try} instance. */ @SuppressWarnings("try")/* https://bugs.openjdk.java.net/browse/JDK-8155591 */ public <R> Try<R> of(CheckedFunction3<? super T1, ? super T2, ? super T3, ? extends R> f) { return Try.of(() -> { try (T1 t1 = t1Supplier.apply(); T2 t2 = t2Supplier.apply(); T3 t3 = t3Supplier.apply()) { return f.apply(t1, t2, t3); } }); } }
final T3 val3 = Try.of(() -> gen3.apply(random)).recover(x -> { throw genError(3, size, x); }).get(); try { final Condition condition = Try.of(() -> predicate.apply(val1, val2, val3)).recover(x -> { throw predicateError(x); }).get(); if (condition.precondition) { exhausted = false;
/** * Returns a tupled version of this function. * * @return a tupled function equivalent to this. */ default CheckedFunction1<Tuple3<T1, T2, T3>, R> tupled() { return t -> apply(t._1, t._2, t._3); }
/** * Applies this function partially to one argument. * * @param t1 argument 1 * @return a partial application of this function */ default CheckedFunction2<T2, T3, R> apply(T1 t1) { return (T2 t2, T3 t3) -> apply(t1, t2, t3); }
/** * Returns a reversed version of this function. This may be useful in a recursive context. * * @return a reversed function equivalent to this. */ default CheckedFunction3<T3, T2, T1, R> reversed() { return (t3, t2, t1) -> apply(t1, t2, t3); }
/** * Returns a composed function that first applies this CheckedFunction3 to the given argument and then applies * {@linkplain CheckedFunction1} {@code after} to the result. * * @param <V> return type of after * @param after the function applied after this * @return a function composed of this and after * @throws NullPointerException if after is null */ default <V> CheckedFunction3<T1, T2, T3, V> andThen(CheckedFunction1<? super R, ? extends V> after) { Objects.requireNonNull(after, "after is null"); return (t1, t2, t3) -> after.apply(apply(t1, t2, t3)); }
/** * Lifts the given {@code partialFunction} into a total function that returns an {@code Try} result. * * @param partialFunction a function that is not defined for all values of the domain (e.g. by throwing) * @param <R> return type * @param <T1> 1st argument * @param <T2> 2nd argument * @param <T3> 3rd argument * @return a function that applies arguments to the given {@code partialFunction} and returns {@code Success(result)} * if the function is defined for the given arguments, and {@code Failure(throwable)} otherwise. */ static <T1, T2, T3, R> Function3<T1, T2, T3, Try<R>> liftTry(CheckedFunction3<? super T1, ? super T2, ? super T3, ? extends R> partialFunction) { return (t1, t2, t3) -> Try.of(() -> partialFunction.apply(t1, t2, t3)); }
@Test public void testC3() throws Throwable { CheckedFunction3<String, String, String, String> src = (i1, i2, i3) -> i1 + i2 + i3 + 42; String json = mapper().writer().writeValueAsString(src); CheckedFunction3<String, String, String, String> res = mapper().readValue(json, new TypeReference<CheckedFunction3<String, String, String, String>>() {}); Assert.assertEquals(res.apply("1/", "2/", "3/"), "1/2/3/42"); }