NonEmptyList

class NonEmptyList<out A>(val head: A, val tail: List<A>) : AbstractList<A> , NonEmptyCollection<A> (source)

NonEmptyList is a data type used in Λrrow to model ordered lists that guarantee to have at least one value.

Constructing NonEmptyList

A NonEmptyList guarantees the list always has at least 1 element.

import arrow.core.nonEmptyListOf
import arrow.core.toNonEmptyListOrNull

fun main() {
println(nonEmptyListOf(1, 2, 3, 4, 5))
println(listOf(1, 2, 3).toNonEmptyListOrNull())
println(emptyList<Int>().toNonEmptyListOrNull())
}
NonEmptyList(1, 2, 3, 4, 5)
NonEmptyList(1, 2, 3)
null

head

Unlike List[0], NonEmptyList.head it's a safe operation that guarantees no exception throwing.

import arrow.core.nonEmptyListOf

val value =
//sampleStart
nonEmptyListOf(1, 2, 3, 4, 5).head
//sampleEnd
fun main() {
println(value)
}

foldLeft

When we fold over a NonEmptyList, we turn a NonEmptyList< A > into B by providing a seed value and a function that carries the state on each iteration over the elements of the list. The first argument is a function that addresses the seed value, this can be any object of any type which will then become the resulting typed value. The second argument is a function that takes the current state and element in the iteration and returns the new state after transformations have been applied.

import arrow.core.NonEmptyList
import arrow.core.nonEmptyListOf

//sampleStart
fun sumNel(nel: NonEmptyList<Int>): Int =
nel.foldLeft(0) { acc, n -> acc + n }
val value = sumNel(nonEmptyListOf(1, 1, 1, 1))
//sampleEnd
fun main() {
println("value = $value")
}

map

map allows us to transform A into B in NonEmptyList< A >

import arrow.core.nonEmptyListOf

val value =
//sampleStart
nonEmptyListOf(1, 1, 1, 1).map { it + 1 }
//sampleEnd
fun main() {
println(value)
}

Combining NonEmptyLists

flatMap

flatMap allows us to compute over the contents of multiple NonEmptyList< * > values

import arrow.core.NonEmptyList
import arrow.core.nonEmptyListOf

//sampleStart
val nelOne: NonEmptyList<Int> = nonEmptyListOf(1, 2, 3)
val nelTwo: NonEmptyList<Int> = nonEmptyListOf(4, 5)

val value = nelOne.flatMap { one ->
nelTwo.map { two ->
one + two
}
}
//sampleEnd
fun main() {
println("value = $value")
}

zip

Λrrow contains methods that allow you to preserve type information when computing over different NonEmptyList typed values.

import arrow.core.NonEmptyList
import arrow.core.nonEmptyListOf
import kotlin.random.Random

data class Person(val id: Long, val name: String, val year: Int)

// Note each NonEmptyList is of a different type
val nelId: NonEmptyList<Long> = nonEmptyListOf(Random.nextLong(), Random.nextLong())
val nelName: NonEmptyList<String> = nonEmptyListOf("William Alvin Howard", "Haskell Curry")
val nelYear: NonEmptyList<Int> = nonEmptyListOf(1926, 1900)

val value = nelId.zip(nelName, nelYear) { id, name, year ->
Person(id, name, year)
}
//sampleEnd
fun main() {
println("value = $value")
}

Summary

  • NonEmptyList is used to model lists that guarantee at least one element

  • We can easily construct values of NonEmptyList with nonEmptyListOf

  • foldLeft, map, flatMap and others are used to compute over the internal contents of a NonEmptyList value.

  • a.zip(b, c) { ... } can be used to compute over multiple NonEmptyList values preserving type information and abstracting over arity with zip

Constructors

Link copied to clipboard
constructor(head: A, tail: List<A>)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
val all: List<A>
Link copied to clipboard
open override val head: A
Link copied to clipboard
open override val size: Int
Link copied to clipboard
val tail: List<A>

Functions

Link copied to clipboard
Link copied to clipboard
fun <A, B> Iterable<A>.align(b: Iterable<B>): List<Ior<A, B>>

Combines two structures by taking the union of their shapes and using Ior to hold the elements.

inline fun <A, B, C> Iterable<A>.align(b: Iterable<B>, fa: (Ior<A, B>) -> C): List<C>

Combines two structures by taking the union of their shapes and combining the elements with the given function.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
operator fun <A : Comparable<A>> NonEmptyList<A>.compareTo(other: NonEmptyList<A>): Int
operator fun <A : Comparable<A>> Iterable<A>.compareTo(other: Iterable<A>): Int
Link copied to clipboard
open operator override fun contains(element: A): Boolean
Link copied to clipboard
open override fun containsAll(elements: Collection<A>): Boolean
Link copied to clipboard
fun <A, B> Iterable<A>.crosswalk(f: (A) -> Iterable<B>): List<List<B>>
Link copied to clipboard
fun <A, K, V> Iterable<A>.crosswalkMap(f: (A) -> Map<K, V>): Map<K, List<V>>
Link copied to clipboard
fun <A, B> Iterable<A>.crosswalkNull(f: (A) -> B?): List<B>?
Link copied to clipboard
open fun distinct(): NonEmptyList<A>
Link copied to clipboard
open inline override fun <K> distinctBy(selector: (A) -> K): NonEmptyList<A>
Link copied to clipboard

Returns an element as Some at the given index or None if the index is out of bounds of this iterable.

Link copied to clipboard
open operator override fun equals(other: Any?): Boolean
Link copied to clipboard
fun extract(): A
Link copied to clipboard
Link copied to clipboard

Returns the first element as Some, or None if the iterable is empty.

inline fun <T> Iterable<T>.firstOrNone(predicate: (T) -> Boolean): Option<T>

Returns the first element as Some matching the given predicate, or None if element was not found.

Link copied to clipboard
open fun firstOrNull(): A
Link copied to clipboard
open inline override fun <B> flatMap(transform: (A) -> NonEmptyCollection<B>): NonEmptyList<B>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Flatten an Iterable of Either. Alias for mapOrAccumulate over an Iterable of computed Either. Either returns a List containing all Either.Right values, or a NonEmptyList of all Either.Left values.

@JvmName(name = "flattenNelOrAccumulate")
fun <Error, A> Iterable<EitherNel<Error, A>>.flattenOrAccumulate(): Either<NonEmptyList<Error>, List<A>>

Flatten an Iterable of Either. Alias for mapOrAccumulate over an Iterable of computed Either. Either returns a List containing all Either.Right values, or a NonEmptyList of all EitherNel values.

Flatten an Iterable of Either. Alias for mapOrAccumulate over an Iterable of computed Either. Either returns a List containing all Either.Right values, or Either.Left values accumulated using combine.

@JvmName(name = "flattenNelOrAccumulate")
fun <Error, A> Iterable<EitherNel<Error, A>>.flattenOrAccumulate(combine: (Error, Error) -> Error): Either<Error, List<A>>

Flatten an Iterable of Either. Alias for mapOrAccumulate over an Iterable of computed Either. Either returns a List containing all Either.Right values, or EitherNel values accumulated using combine.

Link copied to clipboard
inline fun <B> foldLeft(b: B, f: (B, A) -> B): B
Link copied to clipboard
open operator override fun get(index: Int): A
Link copied to clipboard
open override fun hashCode(): Int
Link copied to clipboard
open override fun indexOf(element: A): Int
Link copied to clipboard
fun <A> Iterable<A>.interleave(other: Iterable<A>): List<A>

Interleaves the elements of this Iterable with those of other. Elements of this and other are taken in turn, and the resulting list is the concatenation of the interleaved elements. If one Iterable is longer than the other, the remaining elements are appended to the end.

Link copied to clipboard
open override fun isEmpty(): Boolean
Link copied to clipboard
open operator override fun iterator(): Iterator<A>
Link copied to clipboard
open override fun lastIndexOf(element: A): Int
Link copied to clipboard

Returns the last element as Some, or None if the iterable is empty.

inline fun <T> Iterable<T>.lastOrNone(predicate: (T) -> Boolean): Option<T>

Returns the last element as Some matching the given predicate, or None if no such element was found.

Link copied to clipboard
open override fun lastOrNull(): A
Link copied to clipboard
fun <A, B> Iterable<A>.leftPadZip(other: Iterable<B>): List<Pair<A?, B>>

Returns a List containing the zipped values of the two lists with null for padding on the left.

inline fun <A, B, C> Iterable<A>.leftPadZip(other: Iterable<B>, fab: (A?, B) -> C): List<C>

Returns a List containing the result of applying some transformation (A?, B) -> C on a zip, excluding all cases where the right value is null.

Link copied to clipboard
open override fun listIterator(): ListIterator<A>
open override fun listIterator(index: Int): ListIterator<A>
Link copied to clipboard
open inline override fun <B> map(transform: (A) -> B): NonEmptyList<B>
Link copied to clipboard
open inline override fun <B> mapIndexed(transform: (index: Int, A) -> B): NonEmptyList<B>
Link copied to clipboard
inline fun <E, A, B> NonEmptyList<A>.mapOrAccumulate(combine: (E, E) -> E, transform: RaiseAccumulate<E>.(A) -> B): Either<E, NonEmptyList<B>>

Returns Either a List containing the results of applying the given transform function to each element in the original collection, or accumulate all the logical errors into a NonEmptyList that were raised while applying the transform function.

inline fun <Error, A, B> Iterable<A>.mapOrAccumulate(combine: (Error, Error) -> Error, transform: RaiseAccumulate<Error>.(A) -> B): Either<Error, List<B>>

Returns Either a List containing the results of applying the given transform function to each element in the original collection, or accumulate all the logical errors that were raised while transforming the collection using the combine function is used to accumulate all the logical errors.

Link copied to clipboard
inline fun <T : Comparable<T>> NonEmptyList<T>.max(): T
Link copied to clipboard
inline fun <A, B : Comparable<B>> NonEmptyList<A>.maxBy(selector: (A) -> B): A
Link copied to clipboard
inline fun <T : Comparable<T>> NonEmptyList<T>.min(): T
Link copied to clipboard
inline fun <A, B : Comparable<B>> NonEmptyList<A>.minBy(selector: (A) -> B): A
Link copied to clipboard
fun <B> padZip(other: NonEmptyList<B>): NonEmptyList<Pair<A?, B?>>
inline fun <B, C> padZip(other: NonEmptyList<B>, left: (A) -> C, right: (B) -> C, both: (A, B) -> C): NonEmptyList<C>
Link copied to clipboard
fun <A, B> Iterable<A>.padZip(other: Iterable<B>): List<Pair<A?, B?>>

Returns a List containing the zipped values of the two lists with null for padding.

inline fun <A, B, C> Iterable<A>.padZip(other: Iterable<B>, fa: (A?, B?) -> C): List<C>

Returns a List containing the result of applying some transformation (A?, B?) -> C on a zip.

inline fun <A, B, C> Iterable<A>.padZip(other: Iterable<B>, left: (A) -> C, right: (B) -> C, both: (A, B) -> C): List<C>
Link copied to clipboard
open operator override fun plus(element: @UnsafeVariance A): NonEmptyList<A>
open operator override fun plus(elements: Iterable<@UnsafeVariance A>): NonEmptyList<A>
Link copied to clipboard
inline fun <A, B> Iterable<A>.reduceOrNull(initial: (A) -> B, operation: (acc: B, A) -> B): B?
Link copied to clipboard
inline fun <A, B> List<A>.reduceRightNull(initial: (A) -> B, operation: (A, acc: B) -> B): B?
Link copied to clipboard
fun <A, B> Iterable<A>.rightPadZip(other: Iterable<B>): List<Pair<A, B?>>

Returns a List> containing the zipped values of the two lists with null for padding on the right.

inline fun <A, B, C> Iterable<A>.rightPadZip(other: Iterable<B>, fa: (A, B?) -> C): List<C>

Returns a List containing the result of applying some transformation (A, B?) -> C on a zip, excluding all cases where the left value is null.

Link copied to clipboard

Separate the inner Either values into the Either.Left and Either.Right.

inline fun <T, A, B> Iterable<T>.separateEither(f: (T) -> Either<A, B>): Pair<List<A>, List<B>>

Applies a function f to each element and returns a pair of arrays: the first one made of those values returned by f that were wrapped in Either.Left, and the second one made of those wrapped in Either.Right.

Link copied to clipboard
fun <A, B> Iterable<Ior<A, B>>.separateIor(): Pair<List<A>, List<B>>

splits a union into its component parts.

Link copied to clipboard

Returns single element as Some, or None if the iterable is empty or has more than one element.

inline fun <T> Iterable<T>.singleOrNone(predicate: (T) -> Boolean): Option<T>

Returns the single element as Some matching the given predicate, or None if element was not found or more than one element was found.

Link copied to clipboard
fun <A> Iterable<A>.split(): Pair<List<A>, A>?

Attempt to split the Iterable into the tail and the first element. Returns null if the Iterable is empty, otherwise returns a Pair of the tail and the first element.

Link copied to clipboard
open override fun subList(fromIndex: Int, toIndex: Int): List<A>
Link copied to clipboard
fun <A> Iterable<A>.tail(): List<A>

Alias for drop(1)

Link copied to clipboard
fun toList(): List<A>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open override fun toString(): String
Link copied to clipboard
fun <A, B> Iterable<A>.unweave(ffa: (A) -> Iterable<B>): List<B>

interleaves the elements produced by applying ffa to every element of this Iterable.

Link copied to clipboard
Link copied to clipboard
inline fun <B, Z> zip(b: NonEmptyList<B>, map: (A, B) -> Z): NonEmptyList<Z>
inline fun <B, C, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, map: (A, B, C) -> Z): NonEmptyList<Z>
inline fun <B, C, D, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, map: (A, B, C, D) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, map: (A, B, C, D, E) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, F, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, f: NonEmptyList<F>, map: (A, B, C, D, E, F) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, F, G, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, f: NonEmptyList<F>, g: NonEmptyList<G>, map: (A, B, C, D, E, F, G) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, F, G, H, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, f: NonEmptyList<F>, g: NonEmptyList<G>, h: NonEmptyList<H>, map: (A, B, C, D, E, F, G, H) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, F, G, H, I, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, f: NonEmptyList<F>, g: NonEmptyList<G>, h: NonEmptyList<H>, i: NonEmptyList<I>, map: (A, B, C, D, E, F, G, H, I) -> Z): NonEmptyList<Z>
inline fun <B, C, D, E, F, G, H, I, J, Z> zip(b: NonEmptyList<B>, c: NonEmptyList<C>, d: NonEmptyList<D>, e: NonEmptyList<E>, f: NonEmptyList<F>, g: NonEmptyList<G>, h: NonEmptyList<H>, i: NonEmptyList<I>, j: NonEmptyList<J>, map: (A, B, C, D, E, F, G, H, I, J) -> Z): NonEmptyList<Z>
Link copied to clipboard
inline fun <B, C, D, E> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, transform: (B, C, D) -> E): List<E>
inline fun <B, C, D, E, F> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, transform: (B, C, D, E) -> F): List<F>
inline fun <B, C, D, E, F, G> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, transform: (B, C, D, E, F) -> G): List<G>
inline fun <B, C, D, E, F, G, H> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, g: Iterable<G>, transform: (B, C, D, E, F, G) -> H): List<H>
inline fun <B, C, D, E, F, G, H, I> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, g: Iterable<G>, h: Iterable<H>, transform: (B, C, D, E, F, G, H) -> I): List<I>
inline fun <B, C, D, E, F, G, H, I, J> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, g: Iterable<G>, h: Iterable<H>, i: Iterable<I>, transform: (B, C, D, E, F, G, H, I) -> J): List<J>
inline fun <B, C, D, E, F, G, H, I, J, K> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, g: Iterable<G>, h: Iterable<H>, i: Iterable<I>, j: Iterable<J>, transform: (B, C, D, E, F, G, H, I, J) -> K): List<K>
inline fun <B, C, D, E, F, G, H, I, J, K, L> Iterable<B>.zip(c: Iterable<C>, d: Iterable<D>, e: Iterable<E>, f: Iterable<F>, g: Iterable<G>, h: Iterable<H>, i: Iterable<I>, j: Iterable<J>, k: Iterable<K>, transform: (B, C, D, E, F, G, H, I, J, K) -> L): List<L>