Skip to content

Instantly share code, notes, and snippets.

@7h3kk1d
Created July 22, 2022 22:23
Show Gist options
  • Save 7h3kk1d/0acfc3bb6e9a5f98fa1b89b55c3650f7 to your computer and use it in GitHub Desktop.
Save 7h3kk1d/0acfc3bb6e9a5f98fa1b89b55c3650f7 to your computer and use it in GitHub Desktop.
Failable Monad
public sealed interface Failable<A> extends CoProduct2<List<String>, A, Failable<A>>, Monad<A, Failable<?>> {
@Override
default <B> Failable<B> flatMap(Fn1<? super A, ? extends Monad<B, Failable<?>>> fn1) {
return match(Failed::new, fn1.fmap(Monad::coerce));
}
@Override
default <B> Failable<B> pure(B b) {
return new Success<>(b);
}
@Override
default <B> Failable<B> zip(Applicative<Fn1<? super A, ? extends B>, Failable<?>> appFn) {
Failable<Fn1<? super A, ? extends B>> coerce = appFn.coerce();
return match(failures -> coerce.match(otherFailures -> new Failed<>(addAll(ArrayList::new,
failures,
otherFailures)),
constantly(new Failed<>(failures))),
a -> coerce.match(Failed::new,
fn -> new Success<>(fn.apply(a))));
}
record Failed<A>(List<String> failures) implements Failable<A> {
@Override
public <R> R match(Fn1<? super List<String>, ? extends R> fn1, Fn1<? super A, ? extends R> fn11) {
return fn1.apply(failures);
}
}
record Success<A>(A value) implements Failable<A> {
@Override
public <R> R match(Fn1<? super List<String>, ? extends R> fn1, Fn1<? super A, ? extends R> fn11) {
return fn11.apply(value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment