com.github.tonivade.purefun.instances.TryInstances 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.Function2;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Pattern2;
import com.github.tonivade.purefun.Witness;
import com.github.tonivade.purefun.type.Eval;
import com.github.tonivade.purefun.type.Try;
import com.github.tonivade.purefun.type.TryOf;
import com.github.tonivade.purefun.type.Try_;
import com.github.tonivade.purefun.typeclasses.Applicative;
import com.github.tonivade.purefun.typeclasses.Foldable;
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.Traverse;
public interface TryInstances {
static Eq> eq(Eq eqSuccess) {
final Eq eqFailure = Eq.throwable();
return (a, b) -> Pattern2., Try, Boolean>build()
.when((x, y) -> x.isFailure() && y.isFailure())
.then((x, y) -> eqFailure.eqv(x.getCause(), y.getCause()))
.when((x, y) -> x.isSuccess() && y.isSuccess())
.then((x, y) -> eqSuccess.eqv(x.get(), y.get()))
.otherwise()
.returns(false)
.apply(TryOf.narrowK(a), TryOf.narrowK(b));
}
static Functor functor() {
return TryFunctor.INSTANCE;
}
static Applicative applicative() {
return TryApplicative.INSTANCE;
}
static Monad monad() {
return TryMonad.INSTANCE;
}
static MonadError monadError() {
return TryMonadError.INSTANCE;
}
static MonadThrow monadThrow() {
return TryMonadThrow.INSTANCE;
}
static Foldable foldable() {
return TryFoldable.INSTANCE;
}
static Traverse traverse() {
return TryTraverse.INSTANCE;
}
}
interface TryFunctor extends Functor {
TryFunctor INSTANCE = new TryFunctor() {};
@Override
default Kind map(Kind value, Function1 mapper) {
return TryOf.narrowK(value).map(mapper);
}
}
interface TryPure extends Applicative {
@Override
default Kind pure(T value) {
return Try.success(value);
}
}
interface TryApplicative extends TryPure {
TryApplicative INSTANCE = new TryApplicative() {};
@Override
default Kind ap(Kind value, Kind> apply) {
return TryOf.narrowK(value).flatMap(t -> TryOf.narrowK(apply).map(f -> f.apply(t)));
}
}
interface TryMonad extends TryPure, Monad {
TryMonad INSTANCE = new TryMonad() {};
@Override
default Kind flatMap(Kind value,
Function1> map) {
return TryOf.narrowK(value).flatMap(map.andThen(TryOf::narrowK));
}
}
interface TryMonadError extends TryMonad, MonadError {
TryMonadError INSTANCE = new TryMonadError() {};
@Override
default Kind raiseError(Throwable error) {
return Try.failure(error);
}
@Override
default Kind handleErrorWith(Kind value,
Function1> handler) {
return TryOf.narrowK(value).fold(handler.andThen(TryOf::narrowK), Try::success);
}
}
interface TryMonadThrow extends TryMonadError, MonadThrow {
TryMonadThrow INSTANCE = new TryMonadThrow() {};
}
interface TryFoldable extends Foldable {
TryFoldable INSTANCE = new TryFoldable() {};
@Override
default B foldLeft(Kind value, B initial, Function2 mapper) {
return TryOf.narrowK(value).fold(t -> initial, a -> mapper.apply(initial, a));
}
@Override
default Eval foldRight(Kind value, Eval initial,
Function2, Eval> mapper) {
return TryOf.narrowK(value).fold(t -> initial, a -> mapper.apply(a, initial));
}
}
interface TryTraverse extends Traverse, TryFoldable {
TryTraverse INSTANCE = new TryTraverse() {};
@Override
default Kind> traverse(
Applicative applicative, Kind value,
Function1> mapper) {
return TryOf.narrowK(value).fold(
t -> applicative.pure(Try.failure(t)),
t -> applicative.map(mapper.apply(t), x -> Try.success(x)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy