All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.tonivade.purefun.instances.ZIOInstances 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.concurrent.FutureOf.toFuture;
import static com.github.tonivade.purefun.effect.ZIOOf.toZIO;
import static com.github.tonivade.purefun.instances.FutureInstances.async;

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.Unit;
import com.github.tonivade.purefun.concurrent.Future;
import com.github.tonivade.purefun.effect.UIO;
import com.github.tonivade.purefun.effect.ZIO;
import com.github.tonivade.purefun.effect.ZIOOf;
import com.github.tonivade.purefun.effect.ZIO_;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Bracket;
import com.github.tonivade.purefun.typeclasses.Console;
import com.github.tonivade.purefun.typeclasses.Defer;
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 ZIOInstances {

  static  Functor, E>> functor() {
    return ZIOFunctor.INSTANCE;
  }

  static  Applicative, E>> applicative() {
    return ZIOApplicative.INSTANCE;
  }

  static  Monad, E>> monad() {
    return ZIOMonad.INSTANCE;
  }

  static  MonadError, E>, E> monadError() {
    return ZIOMonadError.INSTANCE;
  }

  static  MonadThrow, Throwable>> monadThrow() {
    return ZIOMonadThrow.INSTANCE;
  }

  static  MonadDefer, Throwable>> monadDefer() {
    return ZIOMonadDefer.INSTANCE;
  }

  static  Console, Throwable>> console() {
    return ZIOConsole.INSTANCE;
  }
  
  static  Runtime, E>> runtime(R env) {
    return ZIORuntime.instance(env);
  }
}

interface ZIOFunctor extends Functor, E>> {

  @SuppressWarnings("rawtypes")
  ZIOFunctor INSTANCE = new ZIOFunctor() {};

  @Override
  default  ZIO map(
      Kind, E>, ? extends A> value, 
      Function1 map) {
    return ZIOOf.narrowK(value).map(map);
  }
}

interface ZIOPure extends Applicative, E>> {

  @Override
  default  ZIO pure(A value) {
    return ZIO.pure(value);
  }
}

interface ZIOApplicative extends ZIOPure {

  @SuppressWarnings("rawtypes")
  ZIOApplicative INSTANCE = new ZIOApplicative() {};

  @Override
  default  ZIO
          ap(Kind, E>, ? extends A> value,
             Kind, E>, ? extends Function1> apply) {
    return value.fix(ZIOOf::narrowK).ap(apply.fix(ZIOOf::narrowK));
  }
}

interface ZIOMonad extends ZIOPure, Monad, E>> {

  @SuppressWarnings("rawtypes")
  ZIOMonad INSTANCE = new ZIOMonad() {};

  @Override
  default  ZIO
          flatMap(Kind, E>, ? extends A> value,
                  Function1, E>, ? extends B>> map) {
    return value.fix(toZIO()).flatMap(map.andThen(ZIOOf::narrowK));
  }
}

interface ZIOMonadError extends ZIOMonad, MonadError, E>, E> {

  @SuppressWarnings("rawtypes")
  ZIOMonadError INSTANCE = new ZIOMonadError() {};

  @Override
  default  ZIO raiseError(E error) {
    return ZIO.raiseError(error);
  }

  @Override
  default  ZIO handleErrorWith(
      Kind, E>, A> value,
      Function1, E>, ? extends A>> handler) {
    // XXX: java8 fails to infer types, I have to do this in steps
    Function1> mapError = handler.andThen(ZIOOf::narrowK);
    Function1> map = ZIO::pure;
    ZIO zio = ZIOOf.narrowK(value);
    return zio.foldM(mapError, map);
  }
}

interface ZIOMonadThrow
    extends ZIOMonadError, MonadThrow, Throwable>> {
  @SuppressWarnings("rawtypes")
  ZIOMonadThrow INSTANCE = new ZIOMonadThrow() {};
}

interface ZIODefer extends Defer, E>> {

  @Override
  default  ZIO
          defer(Producer, E>, ? extends A>> defer) {
    return ZIO.defer(() -> defer.map(ZIOOf::narrowK).get());
  }
}

interface ZIOBracket extends ZIOMonadError, Bracket, E>, E> {

  @Override
  default  ZIO
          bracket(Kind, E>, ? extends A> acquire,
                  Function1, E>, ? extends B>> use,
                  Consumer1 release) {
    return ZIO.bracket(acquire.fix(toZIO()), use.andThen(ZIOOf::narrowK), release);
  }
}

interface ZIOMonadDefer
    extends MonadDefer, Throwable>>, ZIODefer, ZIOBracket {

  @SuppressWarnings("rawtypes")
  ZIOMonadDefer INSTANCE = new ZIOMonadDefer() {};

  @Override
  default ZIO sleep(Duration duration) {
    return UIO.sleep(duration).toZIO();
  }
}

final class ZIOConsole implements Console, Throwable>> {

  @SuppressWarnings("rawtypes")
  protected static final ZIOConsole INSTANCE = new ZIOConsole();

  private final SystemConsole console = new SystemConsole();

  @Override
  public ZIO readln() {
    return ZIO.task(console::readln);
  }

  @Override
  public ZIO println(String text) {
    return ZIO.exec(() -> console.println(text));
  }
}

interface ZIORuntime extends Runtime, E>> {
  
  static  ZIORuntime instance(R env) {
    return () -> env;
  }

  R env();

  @Override
  default  T run(Kind, E>, T> value) {
    return value.fix(toZIO()).provide(env()).getRight();
  }

  @Override
  default  Future parRun(Kind, E>, T> value, Executor executor) {
    return value.fix(toZIO()).foldMap(env(), async(executor)).fix(toFuture());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy