Comment

Comment by marginalia_nu

Either way it feels like optionals are going to be deprecated real quick now we have sealed interfaces and record matching. They let you get rid of so much of the unpleasantness in dealing with this API. Instead you can

    public sealed interface Maybe<T> {

        <T2> Maybe<T2> map(Function<T, T2> mapper);
        <T2> Maybe<T2> flatMap(Function<T, Maybe<T2>> mapper);
        T elseGet(T fallback);

        record Just<T>(T value) implements Maybe<T> {
            public <T2> Maybe<T2> map(Function<T, T2> mapper) {
                return new Just<T2>(mapper.apply(value));
            }
            public <T2> Maybe<T2> flatMap(Function<T, Maybe<T2>> mapper) {
                return mapper.apply(value);
            }
            public T elseGet(T fallback) {
                return value;
            }
        }

        record Empty<T>() implements Maybe<T> {
            public <T2> Maybe<T2>  map(Function<T, T2> mapper) {
                return new Empty<>();
            }
            public <T2> Maybe<T2>  flatMap(Function<T, Maybe<T2>> mapper) {
                return new Empty<>();
            }
            public T elseGet(T fallback) {
                return fallback;
            }
        }

    }

    public void demo() {
        Maybe<String> foo = new Maybe.Empty<String>();

        System.out.println(
            switch (foo) {
                case Maybe.Just(String val) -> "Hello " + val;
                case Maybe.Empty() -> "Fine, leave me hanging";
            }
        );

    };

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton