class Fun {

    public static <M, T, R> Function<T, M>
    composeTry1(final @NotNull Function<? super R, ? extends M> monadUnit,
                final @NotNull Supplier<? extends M> monadZero,
                final @NotNull ThrowingFunction<? super T, ? extends R> mayThrowOnApply,
                final @Nullable BiConsumer<? super T, ? super Exception> onError) {
        final BiConsumer<? super T, ? super Exception> consumeError = onError != null
                ? onError
                : (e, t) -> { /* do nothing */ };

        return element -> {
            try {
                return monadUnit.apply(mayThrowOnApply.tryApply(element));
            } catch (final Exception error) {
                consumeError.accept(element, error);
                return monadZero.get();
            }
        };
    }

    private  Fun();

}