NonEmptyList
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 elementWe can easily construct values of
NonEmptyList
withnonEmptyListOf
foldLeft
,map
,flatMap
and others are used to compute over the internal contents of aNonEmptyList
value.a.zip(b, c) { ... }
can be used to compute over multipleNonEmptyList
values preserving type information and abstracting over arity withzip
Properties
Functions
Combines two structures by taking the union of their shapes and using Ior to hold the elements.
Combines two structures by taking the union of their shapes and combining the elements with the given function.
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.
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.
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.
Returns a List containing the zipped values of the two lists with null for padding on the left.
Returns a List(A?, B) -> C
on a zip, excluding all cases where the right value is null.
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.
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.
Separate the inner Either values into the Either.Left and Either.Right.
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.