Class IO<A>

java.lang.Object
com.jnape.palatable.lambda.io.IO<A>
Type Parameters:
A - the result type
All Implemented Interfaces:
Applicative<A,IO<?>>, Functor<A,IO<?>>, Monad<A,IO<?>>, MonadError<Throwable,A,IO<?>>, MonadRec<A,IO<?>>
Direct Known Subclasses:
IO.Compose

public abstract class IO<A> extends Object implements MonadRec<A,IO<?>>, MonadError<Throwable,A,IO<?>>
A Monad representing some side-effecting computation to be performed. Note that because IO inherently offers an interface supporting parallelism, the optimal execution strategy for any given IO is encoded in its composition.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private static final class 
     
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    IO()
     
  • Method Summary

    Modifier and Type
    Method
    Description
    final IO<A>
    catchError(Fn1<? super Throwable,? extends Monad<A,IO<?>>> recoveryFn)
    Catch any thrown errors inside the Monad and resume normal operations.
    final <B> IO<B>
    discardL(Applicative<B,IO<?>> appB)
    Sequence both this Applicative and appB, discarding this Applicative's result and returning appB.
    final <B> IO<A>
    discardR(Applicative<B,IO<?>> appB)
    Sequence both this Applicative and appB, discarding appB's result and returning this Applicative.
    final IO<A>
    ensuring(IO<?> ensureIO)
    Return an IO that will run ensureIO strictly after running this IO regardless of whether this IO terminates normally, analogous to a finally block.
    final IO<A>
    exceptionally(Fn1<? super Throwable,? extends A> recoveryFn)
    Deprecated.
    in favor of canonical catchError(Fn1)
    static <A> IO<A>
    Static factory method for creating an IO from an externally managed source of completable futures.
    final <B> IO<B>
    flatMap(Fn1<? super A,? extends Monad<B,IO<?>>> f)
    Chain dependent computations that may continue or short-circuit based on previous results.
    final <B> IO<B>
    fmap(Fn1<? super A,? extends B> fn)
    Covariantly transmute this functor's parameter using the given mapping function.
    static <A> IO<A>
    fuse(IO<A> io)
    Fuse all fork opportunities of a given IO such that, unless it is pinned (or is originally externally managed), no parallelism will be used when running it, regardless of what semantics are used when it is executed.
    static <A> IO<A>
    Wrap the given IO in an IO that first checks if the thread the IO runs on is interrupted.
    static <A> IO<A>
    io(A a)
    Static factory method for creating an IO that just returns a when performed.
    static <A> IO<A>
    io(Fn0<? extends A> fn0)
    Static factory method for coercing a lambda to an IO.
    static IO<Unit>
    io(SideEffect sideEffect)
    Static factory method for creating an IO that runs a SideEffect and returns Unit.
    final <B> Lazy<IO<B>>
    lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,IO<?>>> lazyAppFn)
    Given a lazy instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
    static <A> IO<A>
    memoize(IO<A> io)
    Given an IO, return an IO that wraps it, caches its first successful result, and guarantees that no subsequent interactions will happen with it afterwards, returning the cached result thereafter.
    static <A> IO<A>
    monitorSync(Object lock, IO<A> io)
    Synchronize the given IO using the provided lock object.
    static <A> IO<A>
    pin(IO<A> io, Executor executor)
    Pin an IO to an Executor such that regardless of what future decisions are made, when it runs, it will run using whatever parallelism is supported by the Executor's threading model.
    final <B> IO<B>
    pure(B b)
    Lift the value b into this applicative functor.
    static Pure<IO<?>>
    The canonical Pure instance for IO.
    Return a safe IO that will never throw by lifting the result of this IO into Either, catching any Throwable and wrapping it in a left.
    final IO<A>
    throwError(Throwable throwable)
    Throw an error value of type E into the monad.
    static <A> IO<A>
    Produce an IO that throws the given Throwable when executed.
    <B> IO<B>
    trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,IO<?>>> fn)
    Given some operation yielding a RecursiveResult inside this MonadRec, internally trampoline the operation until it yields a termination instruction.
    Returns a CompletableFuture representing the result of this eventual effect.
    Returns a CompletableFuture representing the result of this eventual effect.
    abstract A
    Run the effect represented by this IO instance, blocking the current thread until the effect terminates.
    final <B> IO<B>
    zip(Applicative<Fn1<? super A,? extends B>,IO<?>> appFn)
    Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface com.jnape.palatable.lambda.functor.Functor

    coerce
  • Constructor Details

    • IO

      private IO()
  • Method Details

    • unsafePerformIO

      public abstract A unsafePerformIO()
      Run the effect represented by this IO instance, blocking the current thread until the effect terminates.
      Returns:
      the result of the effect
    • unsafePerformAsyncIO

      public final CompletableFuture<A> unsafePerformAsyncIO()
      Returns a CompletableFuture representing the result of this eventual effect. By default, this will immediately run the effect in terms of the implicit Executor available to CompletableFuture (usually the ForkJoinPool). Note that specific IO constructions may allow this method to delegate to externally-managed CompletableFuture instead of synthesizing their own.
      Returns:
      the CompletableFuture representing this IO's eventual result
      See Also:
    • unsafePerformAsyncIO

      public abstract CompletableFuture<A> unsafePerformAsyncIO(Executor executor)
      Returns a CompletableFuture representing the result of this eventual effect. By default, this will immediately run the effect in terms of the provided Executor. Note that specific IO constructions may allow this method to delegate to externally-managed CompletableFuture instead of synthesizing their own.
      Parameters:
      executor - the Executor to run the CompletableFuture from
      Returns:
      the CompletableFuture representing this IO's eventual result
      See Also:
    • exceptionally

      @Deprecated public final IO<A> exceptionally(Fn1<? super Throwable,? extends A> recoveryFn)
      Deprecated.
      in favor of canonical catchError(Fn1)
      Given a function from any Throwable to the result type A, if this IO successfully yields a result, return it; otherwise, map the Throwable to the result type and return that.
      Parameters:
      recoveryFn - the recovery function
      Returns:
      the guarded IO
    • ensuring

      public final IO<A> ensuring(IO<?> ensureIO)
      Return an IO that will run ensureIO strictly after running this IO regardless of whether this IO terminates normally, analogous to a finally block.
      Parameters:
      ensureIO - the IO to ensure runs strictly after this IO
      Returns:
      the combined IO
    • safe

      public final IO<Either<Throwable,A>> safe()
      Return a safe IO that will never throw by lifting the result of this IO into Either, catching any Throwable and wrapping it in a left.
      Returns:
      the safe IO
    • pure

      public final <B> IO<B> pure(B b)
      Lift the value b into this applicative functor.
      Specified by:
      pure in interface Applicative<A,IO<?>>
      Specified by:
      pure in interface Monad<A,IO<?>>
      Specified by:
      pure in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      pure in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the type of the returned applicative's parameter
      Parameters:
      b - the value
      Returns:
      an instance of this applicative over b
    • fmap

      public final <B> IO<B> fmap(Fn1<? super A,? extends B> fn)
      Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.
      Specified by:
      fmap in interface Applicative<A,IO<?>>
      Specified by:
      fmap in interface Functor<A,IO<?>>
      Specified by:
      fmap in interface Monad<A,IO<?>>
      Specified by:
      fmap in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      fmap in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the new parameter type
      Parameters:
      fn - the mapping function
      Returns:
      a functor over B (the new parameter type)
    • zip

      public final <B> IO<B> zip(Applicative<Fn1<? super A,? extends B>,IO<?>> appFn)
      Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
      Specified by:
      zip in interface Applicative<A,IO<?>>
      Specified by:
      zip in interface Monad<A,IO<?>>
      Specified by:
      zip in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      zip in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the resulting applicative parameter type
      Parameters:
      appFn - the other applicative instance
      Returns:
      the mapped applicative
    • lazyZip

      public final <B> Lazy<IO<B>> lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,IO<?>>> lazyAppFn)
      Given a lazy instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports. This is useful for applicatives that support lazy evaluation and early termination.
      Specified by:
      lazyZip in interface Applicative<A,IO<?>>
      Specified by:
      lazyZip in interface Monad<A,IO<?>>
      Specified by:
      lazyZip in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      lazyZip in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the resulting applicative parameter type
      Parameters:
      lazyAppFn - the lazy other applicative instance
      Returns:
      the mapped applicative
      See Also:
    • discardL

      public final <B> IO<B> discardL(Applicative<B,IO<?>> appB)
      Sequence both this Applicative and appB, discarding this Applicative's result and returning appB. This is generally useful for sequentially performing side-effects.
      Specified by:
      discardL in interface Applicative<A,IO<?>>
      Specified by:
      discardL in interface Monad<A,IO<?>>
      Specified by:
      discardL in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      discardL in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the type of the returned Applicative's parameter
      Parameters:
      appB - the other Applicative
      Returns:
      appB
    • discardR

      public final <B> IO<A> discardR(Applicative<B,IO<?>> appB)
      Sequence both this Applicative and appB, discarding appB's result and returning this Applicative. This is generally useful for sequentially performing side-effects.
      Specified by:
      discardR in interface Applicative<A,IO<?>>
      Specified by:
      discardR in interface Monad<A,IO<?>>
      Specified by:
      discardR in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      discardR in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the type of appB's parameter
      Parameters:
      appB - the other Applicative
      Returns:
      this Applicative
    • flatMap

      public final <B> IO<B> flatMap(Fn1<? super A,? extends Monad<B,IO<?>>> f)
      Chain dependent computations that may continue or short-circuit based on previous results.
      Specified by:
      flatMap in interface Monad<A,IO<?>>
      Specified by:
      flatMap in interface MonadError<Throwable,A,IO<?>>
      Specified by:
      flatMap in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the resulting monad parameter type
      Parameters:
      f - the dependent computation over A
      Returns:
      the new monad instance
    • trampolineM

      public <B> IO<B> trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,IO<?>>> fn)
      Given some operation yielding a RecursiveResult inside this MonadRec, internally trampoline the operation until it yields a termination instruction.

      Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.

      Specified by:
      trampolineM in interface MonadRec<A,IO<?>>
      Type Parameters:
      B - the ultimate resulting carrier type
      Parameters:
      fn - the function to internally trampoline
      Returns:
      the trampolined MonadRec
      See Also:
    • throwError

      public final IO<A> throwError(Throwable throwable)
      Throw an error value of type E into the monad.
      Specified by:
      throwError in interface MonadError<Throwable,A,IO<?>>
      Parameters:
      throwable - the error type
      Returns:
      the monad
    • catchError

      public final IO<A> catchError(Fn1<? super Throwable,? extends Monad<A,IO<?>>> recoveryFn)
      Catch any thrown errors inside the Monad and resume normal operations.
      Specified by:
      catchError in interface MonadError<Throwable,A,IO<?>>
      Parameters:
      recoveryFn - the catch function
      Returns:
      the recovered Monad
    • throwing

      public static <A> IO<A> throwing(Throwable t)
      Produce an IO that throws the given Throwable when executed.
      Type Parameters:
      A - any result type
      Parameters:
      t - the Throwable
      Returns:
      the IO
    • interruptible

      public static <A> IO<A> interruptible(IO<A> io)
      Wrap the given IO in an IO that first checks if the thread the IO runs on is interrupted. If it is, an InterruptedException is thrown; otherwise the given IO is executed as usual. Note that for IOs supporting parallelism, the thread that is checked for interruption may not necessarily be the same thread that the IO ultimately runs on.
      Type Parameters:
      A - the IO result type
      Parameters:
      io - the IO to wrap
      Returns:
      an IO that first checks for thread interrupts
    • monitorSync

      public static <A> IO<A> monitorSync(Object lock, IO<A> io)
      Synchronize the given IO using the provided lock object. Note that to ensure that the entirety of the IO's computation actually runs inside the synchronized region, the IO is executed synchronously inside the synchronized block regardless of the caller's chosen execution strategy.
      Type Parameters:
      A - the IO result type
      Parameters:
      lock - the lock object
      io - the IO
      Returns:
      the synchronized IO
    • fuse

      public static <A> IO<A> fuse(IO<A> io)
      Fuse all fork opportunities of a given IO such that, unless it is pinned (or is originally externally managed), no parallelism will be used when running it, regardless of what semantics are used when it is executed.
      Type Parameters:
      A - the IO result type
      Parameters:
      io - the IO
      Returns:
      the fused IO
      See Also:
    • pin

      public static <A> IO<A> pin(IO<A> io, Executor executor)
      Pin an IO to an Executor such that regardless of what future decisions are made, when it runs, it will run using whatever parallelism is supported by the Executor's threading model. Note that if this IO has already been pinned (or is originally externally managed), pinning to an additional Executor has no meaningful effect.
      Type Parameters:
      A - the IO result type
      Parameters:
      io - the IO
      executor - the Executor
      Returns:
      the IO pinned to the Executor
      See Also:
    • memoize

      public static <A> IO<A> memoize(IO<A> io)
      Given an IO, return an IO that wraps it, caches its first successful result, and guarantees that no subsequent interactions will happen with it afterwards, returning the cached result thereafter. Note that if the underlying IO throws, the failure will not be cached, so subsequent interactions with the memoized IO will again call through to the delegate until it completes normally.
      Type Parameters:
      A - the return type
      Parameters:
      io - the delegate IO
      Returns:
      the memoized IO
    • io

      public static <A> IO<A> io(A a)
      Static factory method for creating an IO that just returns a when performed.
      Type Parameters:
      A - the result type
      Parameters:
      a - the result
      Returns:
      the IO
    • io

      public static <A> IO<A> io(Fn0<? extends A> fn0)
      Static factory method for coercing a lambda to an IO.
      Type Parameters:
      A - the result type
      Parameters:
      fn0 - the lambda to coerce
      Returns:
      the IO
    • io

      public static IO<Unit> io(SideEffect sideEffect)
      Static factory method for creating an IO that runs a SideEffect and returns Unit.
      Parameters:
      sideEffect - the SideEffect
      Returns:
      the IO
    • externallyManaged

      public static <A> IO<A> externallyManaged(Fn0<CompletableFuture<A>> supplier)
      Static factory method for creating an IO from an externally managed source of completable futures.

      Note that constructing an IO this way results in no intermediate futures being constructed by either unsafePerformAsyncIO() or unsafePerformAsyncIO(Executor), and unsafePerformIO() is synonymous with invoking CompletableFuture.get() on the externally managed future.

      Type Parameters:
      A - the result type
      Parameters:
      supplier - the source of externally managed completable futures
      Returns:
      the IO
    • pureIO

      public static Pure<IO<?>> pureIO()
      The canonical Pure instance for IO.
      Returns:
      the Pure instance