|
| 1 | +package com.jnape.palatable.lambda.functions.builtin.fn2; |
| 2 | + |
| 3 | +import com.jnape.palatable.lambda.functions.Fn1; |
| 4 | +import com.jnape.palatable.lambda.functions.Fn2; |
| 5 | +import com.jnape.palatable.lambda.functions.builtin.fn3.Bracket; |
| 6 | +import com.jnape.palatable.lambda.io.IO; |
| 7 | + |
| 8 | +import static com.jnape.palatable.lambda.functions.builtin.fn3.Bracket.bracket; |
| 9 | +import static com.jnape.palatable.lambda.io.IO.io; |
| 10 | + |
| 11 | +/** |
| 12 | + * Given an {@link IO} yielding some {@link AutoCloseable} type <code>A</code> and a kleisli arrow from that type to a |
| 13 | + * new {@link IO} of type <code>B</code>, attempt to provision the <code>A</code>, applying the body operation if |
| 14 | + * provisioning was successful and ensuring that {@link AutoCloseable#close} is called regardless of whether the body |
| 15 | + * succeeds or fails. |
| 16 | + * <p> |
| 17 | + * This is the canonical {@link Bracket bracketing} operation for {@link AutoCloseable AutoCloseables}. |
| 18 | + * |
| 19 | + * @param <A> the initial {@link AutoCloseable} value type to map and clean up |
| 20 | + * @param <B> the resulting type |
| 21 | + * @see Bracket |
| 22 | + */ |
| 23 | +public final class AutoBracket<A extends AutoCloseable, B> implements |
| 24 | + Fn2<IO<A>, Fn1<? super A, ? extends IO<B>>, IO<B>> { |
| 25 | + |
| 26 | + private static final AutoBracket<?, ?> INSTANCE = new AutoBracket<>(); |
| 27 | + |
| 28 | + private AutoBracket() { |
| 29 | + } |
| 30 | + |
| 31 | + @Override |
| 32 | + public IO<B> checkedApply(IO<A> io, Fn1<? super A, ? extends IO<B>> bodyIO) { |
| 33 | + return bracket(io, a -> io(a::close), bodyIO); |
| 34 | + } |
| 35 | + |
| 36 | + @SuppressWarnings("unchecked") |
| 37 | + public static <A extends AutoCloseable, B> AutoBracket<A, B> autoBracket() { |
| 38 | + return (AutoBracket<A, B>) INSTANCE; |
| 39 | + } |
| 40 | + |
| 41 | + public static <A extends AutoCloseable, B> Fn1<Fn1<? super A, ? extends IO<B>>, IO<B>> autoBracket(IO<A> io) { |
| 42 | + return AutoBracket.<A, B>autoBracket().apply(io); |
| 43 | + } |
| 44 | + |
| 45 | + public static <A extends AutoCloseable, B> IO<B> autoBracket(IO<A> io, Fn1<? super A, ? extends IO<B>> bodyIO) { |
| 46 | + return AutoBracket.<A, B>autoBracket(io).apply(bodyIO); |
| 47 | + } |
| 48 | +} |
0 commit comments