diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 22:39:59 -0300 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2017-10-08 22:39:59 -0300 |
| commit | c82e3b3b2de0633317ec8fc85925e91422820597 (patch) | |
| tree | 96567416ce23c5ce85601f9cedc3a94bb1c55cba /base/src/main/java/bjc/utils/data/IHolder.java | |
| parent | b3ac1c8690c3e14c879913e5dcc03a5f5e14876e (diff) | |
Start splitting into maven modules
Diffstat (limited to 'base/src/main/java/bjc/utils/data/IHolder.java')
| -rw-r--r-- | base/src/main/java/bjc/utils/data/IHolder.java | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/base/src/main/java/bjc/utils/data/IHolder.java b/base/src/main/java/bjc/utils/data/IHolder.java new file mode 100644 index 0000000..ca0b2ba --- /dev/null +++ b/base/src/main/java/bjc/utils/data/IHolder.java @@ -0,0 +1,153 @@ +package bjc.utils.data; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.UnaryOperator; + +import bjc.utils.data.internals.BoundListHolder; +import bjc.utils.data.internals.WrappedLazy; +import bjc.utils.data.internals.WrappedOption; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.theory.Functor; + +/** + * A holder of a single value. + * + * @author ben + * + * @param <ContainedType> + * The type of value held + */ +public interface IHolder<ContainedType> extends Functor<ContainedType> { + /** + * Bind a function across the value in this container + * + * @param <BoundType> + * The type of value in this container + * @param binder + * The function to bind to the value + * @return A holder from binding the value + */ + public <BoundType> IHolder<BoundType> bind(Function<ContainedType, IHolder<BoundType>> binder); + + /** + * Apply an action to the value + * + * @param action + * The action to apply to the value + */ + public default void doWith(final Consumer<? super ContainedType> action) { + transform(value -> { + action.accept(value); + + return value; + }); + } + + @Override + default <ArgType, ReturnType> Function<Functor<ArgType>, Functor<ReturnType>> fmap( + final Function<ArgType, ReturnType> func) { + return argumentFunctor -> { + if (!(argumentFunctor instanceof IHolder<?>)) { + final String msg = "This functor only supports mapping over instances of IHolder"; + + throw new IllegalArgumentException(msg); + } + + final IHolder<ArgType> holder = (IHolder<ArgType>) argumentFunctor; + + return holder.map(func); + }; + } + + @Override + public default ContainedType getValue() { + return unwrap(value -> value); + } + + /** + * Lifts a function to bind over this holder + * + * @param <NewType> + * The type of the functions return + * @param func + * The function to lift over the holder + * @return The function lifted over the holder + */ + public <NewType> Function<ContainedType, IHolder<NewType>> lift(Function<ContainedType, NewType> func); + + /** + * Make this holder lazy + * + * @return A lazy version of this holder + */ + public default IHolder<ContainedType> makeLazy() { + return new WrappedLazy<>(this); + } + + /** + * Make this holder a list + * + * @return A list version of this holder + */ + public default IHolder<ContainedType> makeList() { + return new BoundListHolder<>(new FunctionalList<>(this)); + } + + /** + * Make this holder optional + * + * @return An optional version of this holder + */ + public default IHolder<ContainedType> makeOptional() { + return new WrappedOption<>(this); + } + + /** + * Create a new holder with a mapped version of the value in this + * holder. + * + * Does not change the internal state of this holder + * + * @param <MappedType> + * The type of the mapped value + * @param mapper + * The function to do mapping with + * @return A holder with the mapped value + */ + public <MappedType> IHolder<MappedType> map(Function<ContainedType, MappedType> mapper); + + /** + * Replace the held value with a new one + * + * @param newValue + * The value to hold instead + * @return The holder itself + */ + public default IHolder<ContainedType> replace(final ContainedType newValue) { + return transform(oldValue -> { + return newValue; + }); + } + + /** + * Transform the value held in this holder + * + * @param transformer + * The function to transform the value with + * @return The holder itself, for easy chaining + */ + public IHolder<ContainedType> transform(UnaryOperator<ContainedType> transformer); + + /** + * Unwrap the value contained in this holder so that it is no longer + * held + * + * @param <UnwrappedType> + * The type of the unwrapped value + * @param unwrapper + * The function to use to unwrap the value + * @return The unwrapped held value + */ + public <UnwrappedType> UnwrappedType unwrap(Function<ContainedType, UnwrappedType> unwrapper); +} |
