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 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, T> value, Function1 map) {
return ValidationOf.narrowK(value).map(map);
}
}
interface ValidationBifunctor extends Bifunctor {
ValidationBifunctor INSTANCE = new ValidationBifunctor() {};
@Override
default Validation bimap(Kind, B> value,
Function1 leftMap, Function1 rightMap) {
return ValidationOf.narrowK(value).mapError(leftMap).map(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, T> value,
Kind, 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(ValidationOf::narrowK), apply.fix(ValidationOf::narrowK));
}
}
interface ValidationMonad extends ValidationPure, Monad> {
@SuppressWarnings("rawtypes")
ValidationMonad INSTANCE = new ValidationMonad() {};
@Override
default Validation flatMap(Kind, T> value,
Function1, 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, 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