com.github.tonivade.purefun.instances.ValidationInstances 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.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.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) -> {
if (a instanceof Validation.Invalid invalidA && b instanceof Validation.Invalid invalidB) {
return errorEq.eqv(invalidA.getError(), invalidB.getError());
}
if (a instanceof Validation.Valid validA && b instanceof Validation.Valid validB) {
return validEq.eqv(validA.get(), validB.get());
}
return false;
};
}
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 super T, ? extends R> map) {
return ValidationOf.narrowK(value).map(map);
}
}
interface ValidationBifunctor extends Bifunctor {
ValidationBifunctor INSTANCE = new ValidationBifunctor() {};
@Override
default Validation bimap(Kind, ? extends B> value,
Function1 super A, ? extends C> leftMap, Function1 super B, ? extends D> 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 super T, ? extends R>> 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 super A, ? extends B>> 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 super T, ? extends Kind, ? 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 super E, ? extends Kind, ? 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