com.github.tonivade.purefun.instances.EitherTInstances Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2020, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.instances;
import static com.github.tonivade.purefun.Function1.cons;
import static com.github.tonivade.purefun.Precondition.checkNonNull;
import static com.github.tonivade.purefun.Unit.unit;
import java.time.Duration;
import com.github.tonivade.purefun.Consumer1;
import com.github.tonivade.purefun.Eq;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Producer;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.Witness;
import com.github.tonivade.purefun.transformer.EitherT;
import com.github.tonivade.purefun.transformer.EitherTOf;
import com.github.tonivade.purefun.transformer.EitherT_;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.typeclasses.Bracket;
import com.github.tonivade.purefun.typeclasses.Defer;
import com.github.tonivade.purefun.typeclasses.Monad;
import com.github.tonivade.purefun.typeclasses.MonadDefer;
import com.github.tonivade.purefun.typeclasses.MonadError;
import com.github.tonivade.purefun.typeclasses.MonadThrow;
import com.github.tonivade.purefun.typeclasses.Reference;
public interface EitherTInstances {
static Eq, L>, R>> eq(Eq>> eq) {
return (a, b) -> eq.eqv(EitherTOf.narrowK(a).value(), EitherTOf.narrowK(b).value());
}
static Monad, L>> monad(Monad monadF) {
return EitherTMonad.instance(checkNonNull(monadF));
}
static MonadError, L>, L> monadError(Monad monadF) {
return EitherTMonadErrorFromMonad.instance(checkNonNull(monadF));
}
static MonadError, L>, L> monadError(MonadError monadErrorF) {
return EitherTMonadErrorFromMonadError.instance(checkNonNull(monadErrorF));
}
static MonadThrow, Throwable>> monadThrow(Monad monadF) {
return EitherTMonadThrowFromMonad.instance(checkNonNull(monadF));
}
static MonadThrow, Throwable>> monadThrow(MonadThrow monadF) {
return EitherTMonadThrowFromMonadThrow.instance(checkNonNull(monadF));
}
static Defer, L>> defer(MonadDefer monadDeferF) {
return EitherTDefer.instance(checkNonNull(monadDeferF));
}
static MonadDefer, Throwable>> monadDeferFromMonad(MonadDefer monadDeferF) {
return EitherTMonadDeferFromMonad.instance(checkNonNull(monadDeferF));
}
static MonadDefer, Throwable>> monadDeferFromMonadThrow(MonadDefer monadDeferF) {
return EitherTMonadDeferFromMonadThrow.instance(checkNonNull(monadDeferF));
}
static
Reference, Throwable>, A>
refFromMonad(MonadDefer monadDeferF, A value) {
return Reference.of(monadDeferFromMonad(monadDeferF), value);
}
static
Reference, Throwable>, A>
refFromMonadThrow(MonadDefer monadDeferF, A value) {
return Reference.of(monadDeferFromMonadThrow(monadDeferF), value);
}
}
interface EitherTMonad extends Monad, L>> {
static EitherTMonad instance(Monad monadF) {
return () -> monadF;
}
Monad monadF();
@Override
default EitherT pure(T value) {
return EitherT.right(monadF(), value);
}
@Override
default EitherT flatMap(Kind, L>, T> value,
Function1, L>, R>> map) {
return EitherTOf.narrowK(value).flatMap(map.andThen(EitherTOf::narrowK));
}
}
interface EitherTMonadErrorFromMonad
extends MonadError, E>, E>, EitherTMonad {
static EitherTMonadErrorFromMonad instance(Monad monadF) {
return () -> monadF;
}
@Override
default EitherT raiseError(E error) {
return EitherT.left(monadF(), error);
}
@Override
default EitherT handleErrorWith(Kind, E>, A> value,
Function1, E>, A>> handler) {
return EitherT.of(monadF(),
monadF().flatMap(EitherTOf.narrowK(value).value(),
either -> either.fold(
e -> handler.andThen(EitherTOf::narrowK).apply(e).value(),
a -> monadF().pure(Either.right(a)))));
}
}
interface EitherTMonadErrorFromMonadError
extends MonadError, E>, E>,
EitherTMonad {
static EitherTMonadErrorFromMonadError instance(MonadError monadErrorF) {
return () -> monadErrorF;
}
@Override
MonadError monadF();
@Override
default EitherT raiseError(E error) {
return EitherT.of(monadF(), monadF().raiseError(error));
}
@Override
default EitherT handleErrorWith(Kind, E>, A> value,
Function1, E>, A>> handler) {
return EitherT.of(monadF(),
monadF().handleErrorWith(EitherTOf.narrowK(value).value(),
error -> handler.andThen(EitherTOf::narrowK).apply(error).value()));
}
}
interface EitherTMonadThrowFromMonad
extends EitherTMonadErrorFromMonad,
MonadThrow, Throwable>> {
static EitherTMonadThrowFromMonad instance(Monad monadF) {
return () -> monadF;
}
}
interface EitherTMonadThrowFromMonadThrow
extends EitherTMonadErrorFromMonadError,
MonadThrow, Throwable>> {
static EitherTMonadThrowFromMonadThrow instance(MonadThrow monadThrowF) {
return () -> monadThrowF;
}
}
interface EitherTDefer extends Defer, E>> {
static EitherTDefer instance(MonadDefer monadDeferF) {
return () -> monadDeferF;
}
MonadDefer monadF();
@Override
default EitherT defer(Producer, E>, A>> defer) {
return EitherT.of(monadF(), monadF().defer(() -> defer.map(EitherTOf::narrowK).get().value()));
}
}
interface EitherTBracket extends Bracket, Throwable>> {
MonadDefer monadF();
Kind> acquireRecover(Throwable error);
@Override
default EitherT
bracket(Kind, Throwable>, A> acquire,
Function1, Throwable>, B>> use,
Consumer1 release) {
Kind> bracket =
monadF().bracket(
acquire.fix(EitherTOf::narrowK).value(),
either -> either.fold(
this::acquireRecover,
value -> use.andThen(EitherTOf::narrowK).apply(value).value()),
either -> either.fold(cons(unit()), release.asFunction()));
return EitherT.of(monadF(), bracket);
}
}
interface EitherTMonadDeferFromMonad
extends EitherTMonadThrowFromMonad,
EitherTDefer,
EitherTBracket,
MonadDefer, Throwable>> {
static EitherTMonadDeferFromMonad instance(MonadDefer monadDeferF) {
return () -> monadDeferF;
}
@Override
default Kind> acquireRecover(Throwable error) {
return monadF().pure(Either.left(error));
}
@Override
default EitherT sleep(Duration duration) {
return EitherT.of(monadF(), monadF().map(monadF().sleep(duration), Either::right));
}
}
interface EitherTMonadDeferFromMonadThrow
extends EitherTMonadThrowFromMonadThrow,
EitherTDefer,
EitherTBracket,
MonadDefer, Throwable>> {
static EitherTMonadDeferFromMonadThrow instance(MonadDefer monadDeferF) {
return () -> monadDeferF;
}
@Override
default Kind> acquireRecover(Throwable error) {
return monadF().raiseError(error);
}
@Override
default EitherT sleep(Duration duration) {
return EitherT.of(monadF(), monadF().map(monadF().sleep(duration), Either::right));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy