3764 |
|
} |
3765 |
|
|
3766 |
|
static class Monad { |
3767 |
< |
static class MonadError extends Error { |
3768 |
< |
public MonadError() { super("monadic zero"); } |
3767 |
> |
static class ZeroException extends RuntimeException { |
3768 |
> |
public ZeroException() { super("monadic zero"); } |
3769 |
|
} |
3770 |
|
// "return", "unit" |
3771 |
|
static <T> CompletableFuture<T> unit(T value) { |
3773 |
|
} |
3774 |
|
// monadic zero ? |
3775 |
|
static <T> CompletableFuture<T> zero() { |
3776 |
< |
return failedFuture(new MonadError()); |
3776 |
> |
return failedFuture(new ZeroException()); |
3777 |
|
} |
3778 |
|
// >=> |
3779 |
|
static <T,U,V> Function<T, CompletableFuture<V>> compose |
3787 |
|
f.getNow(null); |
3788 |
|
throw new AssertionFailedError("should throw"); |
3789 |
|
} catch (CompletionException success) { |
3790 |
< |
assertTrue(success.getCause() instanceof MonadError); |
3790 |
> |
assertTrue(success.getCause() instanceof ZeroException); |
3791 |
|
} |
3792 |
|
} |
3793 |
|
|
3827 |
|
else if (plus.firstFailure.compareAndSet(null, ex)) { |
3828 |
|
if (plus.isDone()) |
3829 |
|
plus.firstFailure.set(null); |
3830 |
< |
} else { |
3831 |
< |
// prefer failing with first failure |
3832 |
< |
plus.completeExceptionally(plus.firstFailure.getAndSet(null)); |
3830 |
> |
} |
3831 |
> |
else { |
3832 |
> |
// first failure has precedence |
3833 |
> |
Throwable first = plus.firstFailure.getAndSet(null); |
3834 |
> |
|
3835 |
> |
// may fail with "Self-suppression not permitted" |
3836 |
> |
try { first.addSuppressed(ex); } |
3837 |
> |
catch (Exception ignored) {} |
3838 |
> |
|
3839 |
> |
plus.completeExceptionally(first); |
3840 |
|
} |
3841 |
|
}; |
3842 |
|
f.whenComplete(action); |