All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.smallibs.data.Maybe Maven / Gradle / Ivy

There is a newer version: 0.11.0
Show newest version
/*
 * HPAS
 * https://github.com/d-plaindoux/hpas
 *
 * Copyright (c) 2016-2017 Didier Plaindoux
 * Licensed under the LGPL2 license.
 */

package org.smallibs.data;

import org.smallibs.control.Filter;
import org.smallibs.type.HK;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public interface Maybe extends Filter>, HK> {

    static  Maybe some(T value) {
        if (value == null) {
            return none();
        }

        return new Some<>(value);
    }

    static  Maybe none() {
        return new None<>();
    }

    @Override
    default  R accept(Function>, R> f) {
        return f.apply(this);
    }

    @Override
    default Maybe self() {
        return this;
    }

    default Maybe filter(Predicate predicate) {
        return this.flatmap(t -> predicate.test(t) ? this : Maybe.none());
    }

    default  Maybe map(Function mapper) {
        return this.flatmap(x -> some(mapper.apply(x)));
    }

    default  B fold(Function some, Supplier none) {
        return this.map(some).orElse(none);
    }

    default T orElse(T t) {
        return this.orElse(() -> t);
    }

    default boolean hasSome() {
        return this.fold(__ -> true, () -> false);
    }

    Maybe onSome(Consumer onSuccess);

    Maybe onNone(Runnable onNone);

     Maybe flatmap(Function> mapper);

    T orElse(Supplier t);

    /**
     * Some implementation
     */
    final class Some implements Maybe {
        private final T value;

        private Some(T value) {
            this.value = value;
        }

        @Override
        public boolean hasSome() {
            return true;
        }

        @Override
        public  Maybe flatmap(Function> mapper) {
            return mapper.apply(this.value);
        }

        public Maybe onSome(Consumer onSuccess) {
            onSuccess.accept(this.value);
            return this;
        }

        @Override
        public Maybe onNone(Runnable onNone) {
            return this;
        }

        public T orElse(Supplier t) {
            return this.value;
        }

    }

    /**
     * None implementation
     */
    final class None implements Maybe {

        @Override
        public boolean hasSome() {
            return false;
        }

        @Override
        public  Maybe flatmap(Function> mapper) {
            return Maybe.none();
        }

        public Maybe onSome(Consumer onSuccess) {
            return this;
        }

        @Override
        public Maybe onNone(Runnable onNone) {
            onNone.run();
            return this;
        }

        public T orElse(Supplier t) {
            return t.get();
        }
    }

}