package bjc.data.internals; import java.util.function.Function; import java.util.function.UnaryOperator; import bjc.data.IHolder; import bjc.data.Option; /** * A wrapped optional value. * * @author Ben Culkin. * @param * The wrapped type. */ public class WrappedOption implements IHolder { /* The held value. */ private final IHolder> held; /** * Create a new wrapped option. * * @param seedValue * The value to wrap. */ public WrappedOption(final IHolder seedValue) { held = new Option<>(seedValue); } /* * The dummy parameter is to ensure the compiler can pick the right * method, because without this method erases to the same type as the * public one. */ private WrappedOption(final IHolder> toHold, @SuppressWarnings("unused") final boolean dummy) { held = toHold; } @Override public IHolder bind(final Function> binder) { final IHolder> newHolder = held.map((containedHolder) -> { return containedHolder.bind((containedValue) -> { if(containedValue == null) return new Option<>(null); return binder.apply(containedValue); }); }); return new WrappedOption<>(newHolder, false); } @Override public Function> lift(final Function func) { return (val) -> { return new Option<>(func.apply(val)); }; } @Override public IHolder map(final Function mapper) { final IHolder> newHolder = held.map((containedHolder) -> { return containedHolder.map((containedValue) -> { if(containedValue == null) return null; return mapper.apply(containedValue); }); }); return new WrappedOption<>(newHolder, false); } @Override public IHolder transform(final UnaryOperator transformer) { held.transform((containedHolder) -> { return containedHolder.transform((containedValue) -> { if(containedValue == null) return null; return transformer.apply(containedValue); }); }); return this; } @Override public UnwrappedType unwrap(final Function unwrapper) { return held.unwrap((containedHolder) -> { return containedHolder.unwrap((containedValue) -> { if(containedValue == null) return null; return unwrapper.apply(containedValue); }); }); } }