import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; sealed interface Optional<T> { record Empty<T>() implements Optional<T> { } record Present<T>(T value) implements Optional<T> {} default <R> Optional<R> map(Function<T, R> mapper) { return switch (this) { case Present<T>(var value) -> new Present<>(mapper.apply(value)); case Empty<T> _ -> new Empty<>(); }; } default <R> Optional<R> flatMap(Function<T, Optional<R>> mapper) { return switch (this) { case Present<T>(var value) -> mapper.apply(value); case Empty<T> _ -> new Empty<>(); }; } default <R> R fold(Supplier<R> onEmpty, Function<T, R> onPresent) { return switch (this) { case Present<T>(var value) -> onPresent.apply(value); case Empty<T> _ -> onEmpty.get(); }; } default Optional<T> filter(Predicate<T> filter) { return switch (this) { case Present<T>(var value) when filter.test(value) -> this; case Present<T> _ -> new Empty<>(); case Empty<T> _ -> new Empty<>(); }; } }