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

com.github.tonivade.purefun.instances.KleisliInstances 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.Precondition.checkNonNull;
import static com.github.tonivade.purefun.transformer.KleisliOf.toKleisli;

import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.Witness;
import com.github.tonivade.purefun.transformer.Kleisli;
import com.github.tonivade.purefun.transformer.KleisliOf;
import com.github.tonivade.purefun.transformer.Kleisli_;
import com.github.tonivade.purefun.typeclasses.Monad;
import com.github.tonivade.purefun.typeclasses.MonadError;
import com.github.tonivade.purefun.typeclasses.MonadReader;
import com.github.tonivade.purefun.typeclasses.MonadState;

public interface KleisliInstances {

  static  Monad, Z>> monad(Monad monadF) {
    return KleisliMonad.instance(checkNonNull(monadF));
  }

  static  MonadError, Z>, E> monadError(MonadError monadErrorF) {
    return KleisliMonadError.instance(monadErrorF);
  }

  static  MonadReader, Z>, Z> monadReader(Monad monadF) {
    return KleisliMonadReader.instance(monadF);
  }

  static  MonadState, Z>, S> monadState(MonadState monadStateF) {
    return KleisliMonadState.instance(monadStateF);
  }
}

interface KleisliMonad extends Monad, Z>> {

  static  KleisliMonad instance(Monad monadF) {
    return () -> monadF;
  }

  Monad monadF();

  @Override
  default  Kleisli pure(T value) {
    return Kleisli.pure(monadF(), value);
  }

  @Override
  default  Kleisli flatMap(Kind, Z>, ? extends T> value,
      Function1, Z>, ? extends R>> map) {
    return value.fix(toKleisli()).flatMap(map.andThen(KleisliOf::narrowK));
  }
}

interface KleisliMonadError extends MonadError, R>, E>, KleisliMonad {

  static  KleisliMonadError instance(MonadError monadErrorF) {
    return () -> monadErrorF;
  }

  @Override
  MonadError monadF();

  @Override
  default  Kleisli raiseError(E error) {
    return Kleisli.of(monadF(), reader -> monadF().raiseError(error));
  }

  @Override
  default  Kleisli handleErrorWith(
      Kind, R>, A> value,
      Function1, R>, ? extends A>> handler) {
    Kleisli kleisli = value.fix(KleisliOf::narrowK);
    return Kleisli.of(monadF(),
        reader -> monadF().handleErrorWith(kleisli.run(reader),
            error -> handler.apply(error).fix(KleisliOf::narrowK).run(reader)));
  }
}

interface KleisliMonadReader extends MonadReader, R>, R>, KleisliMonad {

  static  KleisliMonadReader instance(Monad monadF) {
    return () -> monadF;
  }

  @Override
  default Kleisli ask() {
    return Kleisli.env(monadF());
  }
}

interface KleisliMonadState extends MonadState, R>, S>, KleisliMonad {

  static  KleisliMonadState instance(MonadState monadStateF) {
    return () -> monadStateF;
  }

  @Override
  MonadState monadF();

  @Override
  default Kleisli set(S state) {
    return Kleisli.of(monadF(), reader -> monadF().set(state));
  }

  @Override
  default Kleisli get() {
    return Kleisli.of(monadF(), reader -> monadF().get());
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy