com.github.tonivade.purefun.instances.EIOInstances Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2022, 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.effect.EIOOf.toEIO;
import java.time.Duration;
import java.util.concurrent.Executor;
import com.github.tonivade.purefun.Consumer1;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Producer;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.concurrent.Future;
import com.github.tonivade.purefun.data.Sequence;
import com.github.tonivade.purefun.effect.EIO;
import com.github.tonivade.purefun.effect.EIOOf;
import com.github.tonivade.purefun.effect.EIO_;
import com.github.tonivade.purefun.effect.UIO;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.type.Try;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Async;
import com.github.tonivade.purefun.typeclasses.Bracket;
import com.github.tonivade.purefun.typeclasses.Concurrent;
import com.github.tonivade.purefun.typeclasses.Defer;
import com.github.tonivade.purefun.typeclasses.Fiber;
import com.github.tonivade.purefun.typeclasses.Functor;
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.Runtime;
@SuppressWarnings("unchecked")
public interface EIOInstances {
static Functor> functor() {
return EIOFunctor.INSTANCE;
}
static Applicative> applicative() {
return EIOApplicative.INSTANCE;
}
static Monad> monad() {
return EIOMonad.INSTANCE;
}
static MonadError, E> monadError() {
return EIOMonadError.INSTANCE;
}
static MonadThrow> monadThrow() {
return EIOMonadThrow.INSTANCE;
}
static MonadDefer> monadDefer() {
return EIOMonadDefer.INSTANCE;
}
static Async> async() {
return EIOAsync.INSTANCE;
}
static Concurrent> concurrent() {
return concurrent(Future.DEFAULT_EXECUTOR);
}
static Concurrent> concurrent(Executor executor) {
return EIOConcurrent.instance(executor);
}
static Runtime> runtime() {
return EIORuntime.INSTANCE;
}
}
interface EIOFunctor extends Functor> {
@SuppressWarnings("rawtypes")
EIOFunctor INSTANCE = new EIOFunctor() {};
@Override
default EIO
map(Kind, ? extends A> value, Function1 super A, ? extends B> map) {
return EIOOf.narrowK(value).map(map);
}
}
interface EIOPure extends Applicative> {
@Override
default EIO pure(A value) {
return EIO.pure(value);
}
}
interface EIOApplicative extends EIOPure {
@SuppressWarnings("rawtypes")
EIOApplicative INSTANCE = new EIOApplicative() {};
@Override
default EIO
ap(Kind, ? extends A> value,
Kind, ? extends Function1 super A, ? extends B>> apply) {
return value.fix(EIOOf::narrowK).ap(apply.fix(EIOOf::narrowK));
}
}
interface EIOMonad extends EIOPure, Monad> {
@SuppressWarnings("rawtypes")
EIOMonad INSTANCE = new EIOMonad() {};
@Override
default EIO
flatMap(Kind, ? extends A> value,
Function1 super A, ? extends Kind, ? extends B>> map) {
return value.fix(toEIO()).flatMap(map.andThen(EIOOf::narrowK));
}
}
interface EIOMonadError extends EIOMonad, MonadError, E> {
@SuppressWarnings("rawtypes")
EIOMonadError INSTANCE = new EIOMonadError() {};
@Override
default EIO raiseError(E error) {
return EIO.raiseError(error);
}
@Override
default EIO handleErrorWith(
Kind, A> value,
Function1 super E, ? extends Kind, ? extends A>> handler) {
// XXX: java8 fails to infer types, I have to do this in steps
Function1 super E, EIO> mapError = handler.andThen(EIOOf::narrowK);
Function1> map = EIO::pure;
EIO eio = EIOOf.narrowK(value);
return eio.foldM(mapError, map);
}
}
interface EIOMonadThrow
extends EIOMonadError,
MonadThrow> {
EIOMonadThrow INSTANCE = new EIOMonadThrow() {};
}
interface EIODefer extends Defer> {
@Override
default EIO
defer(Producer extends Kind, ? extends A>> defer) {
return EIO.defer(defer::get);
}
}
interface EIOBracket extends EIOMonadError, Bracket, E> {
@Override
default EIO
bracket(Kind, ? extends A> acquire,
Function1 super A, ? extends Kind, ? extends B>> use,
Function1 super A, ? extends Kind, Unit>> release) {
return EIO.bracket(acquire, use, release);
}
}
interface EIOMonadDefer
extends MonadDefer>, EIODefer, EIOBracket {
EIOMonadDefer INSTANCE = new EIOMonadDefer() {};
@Override
default EIO sleep(Duration duration) {
return UIO.sleep(duration).toEIO();
}
}
interface EIOAsync extends Async>, EIOMonadDefer {
EIOAsync INSTANCE = new EIOAsync() {};
@Override
default EIO asyncF(Function1>, Kind, Unit>> consumer) {
return EIO.cancellable(cb -> consumer.andThen(EIOOf::narrowK).apply(e -> cb.accept(Try.success(e.toEither()))));
}
}
interface EIOConcurrent extends EIOAsync, Concurrent> {
static EIOConcurrent instance(Executor executor) {
return () -> executor;
}
Executor executor();
@Override
default EIO, B>>, Tuple2, A>, B>>> racePair(
Kind, ? extends A> fa, Kind, ? extends B> fb) {
return EIO.racePair(executor(), fa, fb);
}
@Override
default EIO, A>> fork(Kind, ? extends A> value) {
// TODO Auto-generated method stub
return null;
}
}
interface EIORuntime extends Runtime> {
@SuppressWarnings("rawtypes")
EIORuntime INSTANCE = new EIORuntime() {};
@Override
default T run(Kind, T> value) {
return value.fix(toEIO()).safeRunSync().getRight();
}
@Override
default Sequence run(Sequence, T>> values) {
return run(EIO.traverse(values.map(EIOOf::narrowK)));
}
@Override
default Future parRun(Kind, T> value, Executor executor) {
return value.fix(toEIO()).runAsync().map(Either::get);
}
@Override
default Future> parRun(Sequence, T>> values, Executor executor) {
return parRun(EIO.traverse(values.map(EIOOf::narrowK)), executor);
}
} © 2015 - 2025 Weber Informatics LLC | Privacy Policy