package bjc.data; import java.util.function.Function; import java.util.function.UnaryOperator; import bjc.data.internals.BoundListHolder; import bjc.funcdata.FunctionalList; import bjc.funcdata.ListEx; /** * A holder that represents a set of non-deterministic computations. * * @author ben * * @param * The type of contained value. */ public class ListHolder implements Holder { private ListEx heldValues; /** * Create a new list holder. * * @param values * The possible values for the computation. */ @SafeVarargs public ListHolder(final ContainedType... values) { heldValues = new FunctionalList<>(); if (values != null) { for (final ContainedType containedValue : values) { heldValues.add(containedValue); } } } /* Create a new holder with values. */ private ListHolder(final ListEx toHold) { heldValues = toHold; } @Override public Holder bind(final Function> binder) { final ListEx> boundValues = heldValues.map(binder); return new BoundListHolder<>(boundValues); } @Override public Function> lift(final Function func) { return val -> new ListHolder<>(new FunctionalList<>(func.apply(val))); } @Override public Holder map(final Function mapper) { final ListEx mappedValues = heldValues.map(mapper); return new ListHolder<>(mappedValues); } @Override public Holder transform(final UnaryOperator transformer) { heldValues = heldValues.map(transformer); return this; } @Override public UnwrappedType unwrap(final Function unwrapper) { return unwrapper.apply(heldValues.randItem()); } @Override public String toString() { return String.format("ListHolder [heldValues=%s]", heldValues); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (heldValues == null ? 0 : heldValues.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof ListHolder)) return false; final ListHolder other = (ListHolder) obj; if (heldValues == null) { if (other.heldValues != null) return false; } else if (!heldValues.equals(other.heldValues)) { return false; } return true; } }