Package com.jnape.palatable.lambda.io
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<java.lang.Throwable,A,IO<?>>
,MonadRec<A,IO<?>>
- Direct Known Subclasses:
IO.Compose
public abstract class IO<A> extends java.lang.Object implements MonadRec<A,IO<?>>, MonadError<java.lang.Throwable,A,IO<?>>
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private static class
IO.Compose<A>
-
Constructor Summary
Constructors Modifier Constructor Description private
IO()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Deprecated Methods Modifier and Type Method Description IO<A>
catchError(Fn1<? super java.lang.Throwable,? extends Monad<A,IO<?>>> recoveryFn)
<B> IO<B>
discardL(Applicative<B,IO<?>> appB)
Sequence both thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
.<B> IO<A>
discardR(Applicative<B,IO<?>> appB)
Sequence both thisApplicative
andappB
, discardingappB's
result and returning thisApplicative
.IO<A>
ensuring(IO<?> ensureIO)
IO<A>
exceptionally(Fn1<? super java.lang.Throwable,? extends A> recoveryFn)
Deprecated.in favor of canonicalcatchError(Fn1)
static <A> IO<A>
externallyManaged(Fn0<java.util.concurrent.CompletableFuture<A>> supplier)
Static factory method for creating anIO
from an externally managed source ofcompletable futures
.<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.<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 givenIO
such that, unless it ispinned
(or is originallyexternally managed
), no parallelism will be used when running it, regardless of what semantics are used when it is executed.static <A> IO<A>
interruptible(IO<A> io)
static <A> IO<A>
io(A a)
Static factory method for creating anIO
that just returnsa
when performed.static <A> IO<A>
io(Fn0<? extends A> fn0)
Static factory method for coercing a lambda to anIO
.static IO<Unit>
io(SideEffect sideEffect)
<B> Lazy<IO<B>>
lazyZip(Lazy<? extends Applicative<Fn1<? super A,? extends B>,IO<?>>> lazyAppFn)
Given alazy
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)
static <A> IO<A>
monitorSync(java.lang.Object lock, IO<A> io)
Synchronize the givenIO
using the provided lock object.static <A> IO<A>
pin(IO<A> io, java.util.concurrent.Executor executor)
Pin anIO
to anExecutor
such that regardless of what future decisions are made, when it runs, it will run using whatever parallelism is supported by theExecutor
's threading model.<B> IO<B>
pure(B b)
Lift the valueb
into this applicative functor.static Pure<IO<?>>
pureIO()
IO<Either<java.lang.Throwable,A>>
safe()
IO<A>
throwError(java.lang.Throwable throwable)
Throw an error value of typeE
into themonad
.static <A> IO<A>
throwing(java.lang.Throwable t)
Produce anIO
that throws the givenThrowable
when executed.<B> IO<B>
trampolineM(Fn1<? super A,? extends MonadRec<RecursiveResult<A,B>,IO<?>>> fn)
Given some operation yielding aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
instruction.java.util.concurrent.CompletableFuture<A>
unsafePerformAsyncIO()
Returns aCompletableFuture
representing the result of this eventual effect.abstract java.util.concurrent.CompletableFuture<A>
unsafePerformAsyncIO(java.util.concurrent.Executor executor)
Returns aCompletableFuture
representing the result of this eventual effect.abstract A
unsafePerformIO()
Run the effect represented by thisIO
instance, blocking the current thread until the effect terminates.<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.
-
-
-
Method Detail
-
unsafePerformIO
public abstract A unsafePerformIO()
Run the effect represented by thisIO
instance, blocking the current thread until the effect terminates.- Returns:
- the result of the effect
-
unsafePerformAsyncIO
public final java.util.concurrent.CompletableFuture<A> unsafePerformAsyncIO()
Returns aCompletableFuture
representing the result of this eventual effect. By default, this will immediately run the effect in terms of the implicitExecutor
available toCompletableFuture
(usually theForkJoinPool
). Note that specificIO
constructions may allow this method to delegate to externally-managedCompletableFuture
instead of synthesizing their own.- Returns:
- the
CompletableFuture
representing thisIO
's eventual result - See Also:
unsafePerformAsyncIO(Executor)
-
unsafePerformAsyncIO
public abstract java.util.concurrent.CompletableFuture<A> unsafePerformAsyncIO(java.util.concurrent.Executor executor)
Returns aCompletableFuture
representing the result of this eventual effect. By default, this will immediately run the effect in terms of the providedExecutor
. Note that specificIO
constructions may allow this method to delegate to externally-managedCompletableFuture
instead of synthesizing their own.- Parameters:
executor
- theExecutor
to run theCompletableFuture
from- Returns:
- the
CompletableFuture
representing thisIO
's eventual result - See Also:
unsafePerformAsyncIO()
-
exceptionally
@Deprecated public final IO<A> exceptionally(Fn1<? super java.lang.Throwable,? extends A> recoveryFn)
Deprecated.in favor of canonicalcatchError(Fn1)
Given a function from anyThrowable
to the result typeA
, if thisIO
successfully yields a result, return it; otherwise, map theThrowable
to the result type and return that.- Parameters:
recoveryFn
- the recovery function- Returns:
- the guarded
IO
-
safe
public final IO<Either<java.lang.Throwable,A>> safe()
Return a safeIO
that will never throw by lifting the result of thisIO
intoEither
, catching anyThrowable
and wrapping it in aleft
.- Returns:
- the safe
IO
-
pure
public final <B> IO<B> pure(B b)
Lift the valueb
into this applicative functor.- Specified by:
pure
in interfaceApplicative<A,IO<?>>
- Specified by:
pure
in interfaceMonad<A,IO<?>>
- Specified by:
pure
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
pure
in interfaceMonadRec<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 interfaceApplicative<A,IO<?>>
- Specified by:
fmap
in interfaceFunctor<A,IO<?>>
- Specified by:
fmap
in interfaceMonad<A,IO<?>>
- Specified by:
fmap
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
fmap
in interfaceMonadRec<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 interfaceApplicative<A,IO<?>>
- Specified by:
zip
in interfaceMonad<A,IO<?>>
- Specified by:
zip
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
zip
in interfaceMonadRec<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 alazy
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 interfaceApplicative<A,IO<?>>
- Specified by:
lazyZip
in interfaceMonad<A,IO<?>>
- Specified by:
lazyZip
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
lazyZip
in interfaceMonadRec<A,IO<?>>
- Type Parameters:
B
- the resulting applicative parameter type- Parameters:
lazyAppFn
- the lazy other applicative instance- Returns:
- the mapped applicative
- See Also:
Maybe
,Either
-
discardL
public final <B> IO<B> discardL(Applicative<B,IO<?>> appB)
Sequence both thisApplicative
andappB
, discarding thisApplicative's
result and returningappB
. This is generally useful for sequentially performing side-effects.- Specified by:
discardL
in interfaceApplicative<A,IO<?>>
- Specified by:
discardL
in interfaceMonad<A,IO<?>>
- Specified by:
discardL
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
discardL
in interfaceMonadRec<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 thisApplicative
andappB
, discardingappB's
result and returning thisApplicative
. This is generally useful for sequentially performing side-effects.- Specified by:
discardR
in interfaceApplicative<A,IO<?>>
- Specified by:
discardR
in interfaceMonad<A,IO<?>>
- Specified by:
discardR
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
discardR
in interfaceMonadRec<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 interfaceMonad<A,IO<?>>
- Specified by:
flatMap
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Specified by:
flatMap
in interfaceMonadRec<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 aRecursiveResult
inside thisMonadRec
, internally trampoline the operation until it yields atermination
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 interfaceMonadRec<A,IO<?>>
- Type Parameters:
B
- the ultimate resulting carrier type- Parameters:
fn
- the function to internally trampoline- Returns:
- the trampolined
MonadRec
- See Also:
for a basic implementation
,for a implementation
,for an implementation leveraging an already stack-safe
,for a implementation
-
throwError
public final IO<A> throwError(java.lang.Throwable throwable)
Throw an error value of typeE
into themonad
.- Specified by:
throwError
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Parameters:
throwable
- the error type- Returns:
- the
monad
-
catchError
public final IO<A> catchError(Fn1<? super java.lang.Throwable,? extends Monad<A,IO<?>>> recoveryFn)
- Specified by:
catchError
in interfaceMonadError<java.lang.Throwable,A,IO<?>>
- Parameters:
recoveryFn
- the catch function- Returns:
- the recovered
Monad
-
throwing
public static <A> IO<A> throwing(java.lang.Throwable t)
Produce anIO
that throws the givenThrowable
when executed.- Type Parameters:
A
- any result type- Parameters:
t
- theThrowable
- Returns:
- the
IO
-
interruptible
public static <A> IO<A> interruptible(IO<A> io)
Wrap the givenIO
in anIO
that first checks if thethread
theIO
runs on isinterrupted
. If it is, anInterruptedException
is thrown; otherwise the givenIO
is executed as usual. Note that forIO
s supporting parallelism, the thread that is checked for interruption may not necessarily be the same thread that theIO
ultimately runs on.
-
monitorSync
public static <A> IO<A> monitorSync(java.lang.Object lock, IO<A> io)
Synchronize the givenIO
using the provided lock object. Note that to ensure that the entirety of theIO
's computation actually runs inside the synchronized region, theIO
is executedsynchronously
inside the synchronized block regardless of the caller's chosen execution strategy.
-
fuse
public static <A> IO<A> fuse(IO<A> io)
Fuse all fork opportunities of a givenIO
such that, unless it ispinned
(or is originallyexternally managed
), no parallelism will be used when running it, regardless of what semantics are used when it is executed.- Type Parameters:
A
- theIO
result type- Parameters:
io
- theIO
- Returns:
- the fused
IO
- See Also:
pin(IO, Executor)
-
pin
public static <A> IO<A> pin(IO<A> io, java.util.concurrent.Executor executor)
Pin anIO
to anExecutor
such that regardless of what future decisions are made, when it runs, it will run using whatever parallelism is supported by theExecutor
's threading model. Note that if thisIO
has already been pinned (or is originallyexternally managed
), pinning to an additionalExecutor
has no meaningful effect.
-
memoize
public static <A> IO<A> memoize(IO<A> io)
Given anIO
, return anIO
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 underlyingIO
throws, the failure will not be cached, so subsequent interactions with the memoizedIO
will again call through to the delegate until it completes normally.
-
io
public static <A> IO<A> io(A a)
Static factory method for creating anIO
that just returnsa
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 anIO
.- Type Parameters:
A
- the result type- Parameters:
fn0
- the lambda to coerce- Returns:
- the
IO
-
io
public static IO<Unit> io(SideEffect sideEffect)
- Parameters:
sideEffect
- theSideEffect
- Returns:
- the
IO
-
externallyManaged
public static <A> IO<A> externallyManaged(Fn0<java.util.concurrent.CompletableFuture<A>> supplier)
Static factory method for creating anIO
from an externally managed source ofcompletable futures
.Note that constructing an
IO
this way results in no intermediate futures being constructed by eitherunsafePerformAsyncIO()
orunsafePerformAsyncIO(Executor)
, andunsafePerformIO()
is synonymous with invokingCompletableFuture.get()
on the externally managed future.- Type Parameters:
A
- the result type- Parameters:
supplier
- the source of externally managedcompletable futures
- Returns:
- the
IO
-
-