dev.marksman.enhancediterables.ImmutableNonEmptyIterable Maven / Gradle / Ivy
Show all versions of enhanced-iterables Show documentation
package dev.marksman.enhancediterables;
import com.jnape.palatable.lambda.functions.Fn1;
import com.jnape.palatable.lambda.functions.Fn2;
import com.jnape.palatable.lambda.functions.builtin.fn2.Intersperse;
import com.jnape.palatable.lambda.functions.builtin.fn2.Map;
import com.jnape.palatable.lambda.functions.builtin.fn2.PrependAll;
import com.jnape.palatable.lambda.functions.builtin.fn3.ZipWith;
import com.jnape.palatable.lambda.monoid.builtin.Concat;
import static dev.marksman.enhancediterables.EnhancedIterables.immutableNonEmptyFiniteIterableOrThrow;
import static dev.marksman.enhancediterables.EnhancedIterables.immutableNonEmptyIterableOrThrow;
import static java.util.Objects.requireNonNull;
/**
* An {@code EnhancedIterable} that is safe from mutation, and guaranteed to contain at least one element.
*
* May be infinite or finite.
*
* @param the element type
*/
public interface ImmutableNonEmptyIterable extends ImmutableIterable, NonEmptyIterable {
@Override
ImmutableIterable tail();
/**
* Lazily concatenates an {@code ImmutableIterable} to the end of this {@code ImmutableNonEmptyIterable},
* yielding a new {@code ImmutableNonEmptyIterable}.
*
* @param other an {@link ImmutableIterable}
* @return an {@code ImmutableNonEmptyIterable}
*/
@Override
default ImmutableNonEmptyIterable concat(ImmutableIterable other) {
requireNonNull(other);
return immutableNonEmptyIterableOrThrow(Concat.concat(this, other));
}
/**
* Returns a new {@code ImmutableNonEmptyIterable} by applying a function to all elements of this {@code ImmutableNonEmptyIterable}.
*
* @param f a function from {@code A} to {@code B}.
* This function should be referentially transparent and not perform side-effects.
* It may be called zero or more times for each element.
* @param the type returned by {@code f}
* @return an ImmutableNonEmptyIterable<B>
*/
@Override
default ImmutableNonEmptyIterable fmap(Fn1 super A, ? extends B> f) {
requireNonNull(f);
return immutableNonEmptyIterableOrThrow(Map.map(f, this));
}
/**
* Returns a new {@code ImmutableNonEmptyIterable} with the provided separator value injected between each value of this
* {@code ImmutableNonEmptyIterable}.
*
* If this {@code ImmutableNonEmptyIterable} contains only one element, it is left untouched.
*
* @param separator the separator value
* @return a ImmutableNonEmptyIterable<A>
*/
@Override
default ImmutableNonEmptyIterable intersperse(A separator) {
return immutableNonEmptyIterableOrThrow(Intersperse.intersperse(separator, this));
}
/**
* Returns a new {@code ImmutableNonEmptyIterable} with the provided separator value injected before each value of this
* {@code ImmutableNonEmptyIterable}.
*
* @param separator the separator value
* @return a ImmutableNonEmptyIterable<A>
*/
@Override
default ImmutableNonEmptyIterable prependAll(A separator) {
return immutableNonEmptyIterableOrThrow(PrependAll.prependAll(separator, this));
}
default ImmutableNonEmptyIterable zipWith(Fn2 fn, ImmutableNonEmptyIterable other) {
requireNonNull(fn);
requireNonNull(other);
return immutableNonEmptyIterableOrThrow(ZipWith.zipWith(fn, this, other));
}
default ImmutableNonEmptyFiniteIterable zipWith(Fn2 fn, ImmutableNonEmptyFiniteIterable other) {
requireNonNull(fn);
requireNonNull(other);
return immutableNonEmptyFiniteIterableOrThrow(ZipWith.zipWith(fn, this, other));
}
static ImmutableNonEmptyIterable immutableNonEmptyIterable(A head, ImmutableIterable tail) {
requireNonNull(tail);
return new ImmutableNonEmptyIterable() {
@Override
public A head() {
return head;
}
@Override
public ImmutableIterable tail() {
return tail;
}
};
}
@SafeVarargs
static ImmutableNonEmptyFiniteIterable of(A first, A... more) {
return EnhancedIterables.of(first, more);
}
}