NonEmptyList

class NonEmptyList<out A>(val head: A, val tail: List<A>) : AbstractList<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
fun <out A> NonEmptyList(head: A, tail: List<A>)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
Link copied to clipboard
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
open operator override fun equals(other: Any?): Boolean
Link copied to clipboard
fun extract(): A
Link copied to clipboard
inline fun <B> flatMap(f: (A) -> NonEmptyList<B>): NonEmptyList<B>
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
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
open override fun listIterator(): ListIterator<A>
open override fun listIterator(index: Int): ListIterator<A>
Link copied to clipboard
inline fun <B> map(f: (A) -> B): NonEmptyList<B>
Link copied to clipboard
fun <B> padZip(other: NonEmptyList<B>): NonEmptyList<Pair<A?, B?>>
Link copied to clipboard
operator fun plus(a: @UnsafeVariance A): NonEmptyList<A>
operator fun plus(l: List<@UnsafeVariance A>): NonEmptyList<A>
Link copied to clipboard
Link copied to clipboard
open override fun subList(fromIndex: Int, toIndex: Int): List<A>
Link copied to clipboard
fun toList(): List<A>
Link copied to clipboard
open override fun toString(): String
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>

Properties

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

Extensions

Link copied to clipboard
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.

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.

Link copied to clipboard
open override fun NonEmptyList<Any?>.combine(b: NonEmptyList<Any?>): NonEmptyList<Any?>

Combine two A values.

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
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

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

Link copied to clipboard
Link copied to clipboard

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

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

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

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
fun <A> Iterable<A>.fold(MA: Monoid<A>): A
Link copied to clipboard
fun <A, B> Iterable<A>.foldMap(MB: Monoid<B>, f: (A) -> B): B
Link copied to clipboard
inline fun <A, B> Iterable<A>.ifThen(fb: Iterable<B>, ffa: (A) -> Iterable<B>): Iterable<B>

Logical conditional. The equivalent of Prolog's soft-cut. If its first argument succeeds at all, then the results will be fed into the success branch. Otherwise, the failure branch is taken.

Link copied to clipboard
fun <A> Iterable<A>.interleave(other: Iterable<A>): List<A>

interleave both computations in a fair way.

Link copied to clipboard

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

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

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

Link copied to clipboard
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.

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.

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
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 <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.

Link copied to clipboard
open operator fun NonEmptyList<Any?>.plus(b: NonEmptyList<Any?>): NonEmptyList<Any?>
Link copied to clipboard
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> Iterable<A>.replicate(n: Int): List<List<A>>
fun <A> Iterable<A>.replicate(n: Int, MA: Monoid<A>): List<A>
Link copied to clipboard
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.

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.

Link copied to clipboard
fun <A> Iterable<A>.salign(SG: Semigroup<A>, other: Iterable<A>): Iterable<A>

aligns two structures and combine them with the given Semigroup.combine

Link copied to clipboard

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

Link copied to clipboard

Separate the inner Validated values into the Validated.Invalid and Validated.Valid.

Link copied to clipboard

Returns single element as Some(element), 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(element) 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 computation, giving access to the first result.

Link copied to clipboard
fun <A> Iterable<A>.tail(): List<A>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
inline fun <E, A, B> NonEmptyList<A>.traverse(f: (A) -> Either<E, B>): Either<E, NonEmptyList<B>>
inline fun <E, A, B> NonEmptyList<A>.traverse(semigroup: Semigroup<E>, f: (A) -> Validated<E, B>): Validated<E, NonEmptyList<B>>
inline fun <A, B> NonEmptyList<A>.traverse(f: (A) -> Option<B>): Option<NonEmptyList<B>>
inline fun <E, A, B> Iterable<A>.traverse(f: (A) -> Either<E, B>): Either<E, List<B>>
inline fun <A, B> Iterable<A>.traverse(f: (A) -> Result<B>): Result<List<B>>
inline fun <E, A, B> Iterable<A>.traverse(semigroup: Semigroup<E>, f: (A) -> Validated<E, B>): Validated<E, List<B>>
inline fun <E, A, B> Iterable<A>.traverse(f: (A) -> ValidatedNel<E, B>): ValidatedNel<E, List<B>>
inline fun <A, B> Iterable<A>.traverse(f: (A) -> Option<B>): Option<List<B>>
inline fun <A, B> Iterable<A>.traverse(f: (A) -> B?): List<B>?
Link copied to clipboard
fun <A, B> Iterable<Ior<A, B>>.unalign(): Pair<List<A>, List<B>>

splits a union into its component parts.

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

after applying the given function, splits the resulting union shaped structure into its components parts

Link copied to clipboard
fun <A, B> Iterable<A>.unweave(ffa: (A) -> Iterable<B>): List<B>

Fair conjunction. Similarly to interleave

Link copied to clipboard
fun <A, B, C> NonEmptyList<C>.unzip(f: (C) -> Pair<A, B>): Pair<NonEmptyList<A>, NonEmptyList<B>>

fun <A, B> Iterable<Pair<A, B>>.unzip(): Pair<List<A>, List<B>>

unzips the structure holding the resulting elements in an Pair

inline fun <A, B, C> Iterable<C>.unzip(fc: (C) -> Pair<A, B>): Pair<List<A>, List<B>>

after applying the given function unzip the resulting structure into its elements.

Link copied to clipboard
fun <A> Iterable<A>.void(): List<Unit>
Link copied to clipboard
fun <B, A : B> Iterable<A>.widen(): Iterable<B>

Given A is a sub type of B, re-type this value from Iterable to Iterable

fun <B, A : B> List<A>.widen(): List<B>
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>