Продолжаем эксперименты с java. Когда с версией 1.8 появились
элементы функционального программирования я был очень рад. Ибо действительно
получилось очень удобно и красиво.
Все очень органично смотрелось в классическом ООП коде.
Но на мой взгляд не получило должного развития. Ну или это только для
фанатов функционального программирования и Racket :)
Так вот, регулярно, при миграции старого кода встречаются места где какой то
код обернут в try/catch и просто возвращает fallback значение в случае
исключительной ситуации. Частая ситуация при распознавании дат, чисел и
прочих кастомных форматов.
С использованием классических try/catch в современном коде - особенно на stream api,
вписывается не очень. А тянуть в зависимости для этого цельный VAVR не всегда
позволяют обстоятельства.
В своих проектах я постоянно использую такое расширение.
Монад:
public record Try<T>(T value, Exception error) {
public static <T> Try<T> of(ThrowingSupplier<T> supplier) {
try {
return new Try<>(supplier.get(), null);
} catch (Exception e) {
return new Try<>(null, e);
}
}
public T onError(T fallback) {
return error == null ? value : fallback;
}
}
и к нему функциональный интерфейс:
@FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
теперь в итоге когда нам надо скажем безопасно распознать Integer/Instant/etc…
Integer value = Try.of(() -> Integer.parseInt(fromSomewhere))
.onError(0);
очень красиво вписываемся в стандартные java fp extensions.