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

com.github.tonivade.purefun.free.EitherK 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.free;

import com.github.tonivade.purefun.Equal;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Higher1;
import com.github.tonivade.purefun.HigherKind;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.typeclasses.Comonad;
import com.github.tonivade.purefun.typeclasses.Contravariant;
import com.github.tonivade.purefun.typeclasses.FunctionK;
import com.github.tonivade.purefun.typeclasses.Functor;

import java.io.Serializable;
import java.util.Objects;

import static java.util.Objects.requireNonNull;

@HigherKind
public final class EitherK implements Serializable {

  private static final long serialVersionUID = -2305737717835278018L;

  private static final Equal> EQUAL =
      Equal.>of().comparing(eitherK -> eitherK.either);

  private final Either, Higher1> either;

  private EitherK(Either, Higher1> either) {
    this.either = requireNonNull(either);
  }

  public  EitherK map(Functor functorF, Functor functorG, Function1 mapper) {
    return new EitherK<>(either.bimap(functorF.lift(mapper), functorG.lift(mapper)));
  }

  public  EitherK mapK(FunctionK mapper) {
    return new EitherK<>(either.map(mapper::apply));
  }

  public  EitherK mapLeftK(FunctionK mapper) {
    return new EitherK<>(either.mapLeft(mapper::apply));
  }

  public  Higher1 foldK(FunctionK left, FunctionK right) {
    return either.fold(left::apply, right::apply);
  }

  public  EitherK coflatMap(
      Comonad comonadF, Comonad comonadG, Function1, R> mapper) {
    return new EitherK<>(either.bimap(
        a -> comonadF.coflatMap(a, x -> mapper.apply(left(x))),
        a -> comonadG.coflatMap(a, x -> mapper.apply(right(x)))
    ));
  }

  public T extract(Comonad comonadF, Comonad comonadG) {
    return either.fold(comonadF::extract, comonadG::extract);
  }

  public  EitherK contramap(Contravariant contravariantF, Contravariant contravariantG, Function1 contramap) {
    return new EitherK<>(either.bimap(
        x -> contravariantF.contramap(x, contramap),
        x -> contravariantG.contramap(x, contramap))
    );
  }

  public EitherK swap() {
    return new EitherK<>(either.swap());
  }

  public boolean isLeft() {
    return either.isLeft();
  }

  public boolean isRight() {
    return either.isRight();
  }

  public Higher1 getLeft() {
    return either.getLeft();
  }

  public Higher1 getRight() {
    return either.getRight();
  }

  public static  EitherK left(Higher1 left) {
    return new EitherK<>(Either.left(left));
  }

  public static  EitherK right(Higher1 right) {
    return new EitherK<>(Either.right(right));
  }

  @Override
  public int hashCode() {
    return Objects.hash(either);
  }

  @Override
  public boolean equals(Object obj) {
    return EQUAL.applyTo(this, obj);
  }

  @Override
  public String toString() {
    return "EitherK(" + either + ')';
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy