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

com.github.tonivade.purefun.instances.ValidationInstances 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.type.ValidationOf.toValidation;

import com.github.tonivade.purefun.Eq;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Pattern2;
import com.github.tonivade.purefun.type.Either;
import com.github.tonivade.purefun.type.Validation;
import com.github.tonivade.purefun.type.ValidationOf;
import com.github.tonivade.purefun.type.Validation_;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Bifunctor;
import com.github.tonivade.purefun.typeclasses.Functor;
import com.github.tonivade.purefun.typeclasses.Monad;
import com.github.tonivade.purefun.typeclasses.MonadError;
import com.github.tonivade.purefun.typeclasses.MonadThrow;
import com.github.tonivade.purefun.typeclasses.Selective;
import com.github.tonivade.purefun.typeclasses.Semigroup;

@SuppressWarnings("unchecked")
public interface ValidationInstances {

  static  Eq, T>> eq(Eq errorEq, Eq validEq) {
    return (a, b) -> Pattern2., Validation, Boolean>build()
      .when((x, y) -> x.isInvalid() && y.isInvalid())
        .then((x, y) -> errorEq.eqv(x.getError(), y.getError()))
      .when((x, y) -> x.isValid() && y.isValid())
        .then((x, y) -> validEq.eqv(x.get(), y.get()))
      .otherwise()
        .returns(false)
      .apply(ValidationOf.narrowK(a), ValidationOf.narrowK(b));
  }

  static  Functor> functor() {
    return ValidationFunctor.INSTANCE;
  }

  static Bifunctor bifunctor() {
    return ValidationBifunctor.INSTANCE;
  }

  static  Applicative> applicative(Semigroup semigroup) {
    return ValidationApplicative.instance(semigroup);
  }

  static  Selective> selective(Semigroup semigroup) {
    return ValidationSelective.instance(semigroup);
  }

  static  Monad> monad() {
    return ValidationMonad.INSTANCE;
  }

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

  static MonadThrow> monadThrow() {
    return ValidationMonadThrow.INSTANCE;
  }
}

interface ValidationFunctor extends Functor> {

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

  @Override
  default  Validation map(Kind, ? extends T> value, 
      Function1 map) {
    return ValidationOf.narrowK(value).map(map);
  }
}

interface ValidationBifunctor extends Bifunctor {

  ValidationBifunctor INSTANCE = new ValidationBifunctor() {};

  @Override
  default  Validation bimap(Kind, ? extends B> value,
      Function1 leftMap, Function1 rightMap) {
    return ValidationOf.narrowK(value).bimap(leftMap, rightMap);
  }
}

interface ValidationPure extends Applicative> {

  @Override
  default  Validation pure(T value) {
    return Validation.valid(value);
  }
}

interface ValidationApplicative extends ValidationPure, Applicative> {

  static  ValidationApplicative instance(Semigroup semigroup) {
    return () -> semigroup;
  }

  Semigroup semigroup();

  @Override
  default  Validation ap(Kind, ? extends T> value,
                                     Kind, ? extends Function1> apply) {
    Validation validation = value.fix(ValidationOf::narrowK);
    Validation> validationF = apply.fix(ValidationOf::narrowK);

    if (validation.isValid() && validationF.isValid()) {
      return Validation.valid(validationF.get().apply(validation.get()));
    } else if (validation.isInvalid() && validationF.isValid()) {
      return Validation.invalid(validation.getError());
    } else if (validation.isValid() && validationF.isInvalid()) {
      return Validation.invalid(validationF.getError());
    }

    return Validation.invalid(semigroup().combine(validation.getError(), validationF.getError()));
  }
}

interface ValidationSelective extends ValidationApplicative, Selective> {

  static  ValidationSelective instance(Semigroup semigroup) {
    return () -> semigroup;
  }

  @Override
  default  Validation select(Kind, Either> value,
                                         Kind, Function1> apply) {
    return Validation.select(value.fix(toValidation()), apply.fix(toValidation()));
  }
}

interface ValidationMonad extends ValidationPure, Monad> {

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

  @Override
  default  Validation flatMap(Kind, ? extends T> value,
      Function1, ? extends R>> map) {
    return ValidationOf.narrowK(value).flatMap(map.andThen(ValidationOf::narrowK));
  }
}

interface ValidationMonadError extends ValidationMonad, MonadError, E> {

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

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

  @Override
  default  Validation handleErrorWith(Kind, A> value,
      Function1, ? extends A>> handler) {
    return ValidationOf.narrowK(value).fold(handler.andThen(ValidationOf::narrowK), Validation::valid);
  }
}

interface ValidationMonadThrow
    extends ValidationMonadError,
            MonadThrow> {

  ValidationMonadThrow INSTANCE = new ValidationMonadThrow() {};
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy