Watch video

Video tutorial



NonEmptyList is a data type used in Λrrow to model ordered lists that guarantee to have at least one value. NonEmptyList is available in the arrow-data module under the import

// gradle
compile "io.arrow-kt:arrow-data:$arrow_version"
// namespace


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

NonEmptyList.of(1, 2, 3, 4, 5) // NonEmptyList<Int>
NonEmptyList.of(1, 2) // NonEmptyList<Int>
//NonEmptyList.of() // does not compile

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

NonEmptyList.of(1, 2, 3, 4, 5).head


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.

fun sumNel(nel: NonEmptyList<Int>): Int =
  nel.foldLeft(0) { acc, n -> acc + n }

sumNel(NonEmptyList.of(1, 1, 1, 1))
// 4


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

NonEmptyList.of(1, 1, 1, 1).map { it + 1 }
// NonEmptyList(all=[2, 2, 2, 2])


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

val nelOne: NonEmptyList<Int> = NonEmptyList.of(1)
val nelTwo: NonEmptyList<Int> = NonEmptyList.of(2)

nelOne.flatMap { one -> { two ->
    one + two
// NonEmptyList(all=[3])

Monad binding

Λrrow allows imperative style comprehensions to make computing over NonEmptyList values easy.

import arrow.typeclasses.*
import arrow.instances.*

val nelOne: NonEmptyList<Int> = NonEmptyList.of(1)
val nelTwo: NonEmptyList<Int> = NonEmptyList.of(2)
val nelThree: NonEmptyList<Int> = NonEmptyList.of(3)

ForNonEmptyList extensions {
  binding {
    val one = nelOne.bind()
    val two = nelTwo.bind()
    val three = nelThree.bind()
    one + two + three
// NonEmptyList(all=[6])

Monad binding in NonEmptyList and other collection related data type can be used as generators

ForNonEmptyList extensions {
  binding {
    val x = NonEmptyList.of(1, 2, 3).bind()
    val y = NonEmptyList.of(1, 2, 3).bind()
    x + y
// NonEmptyList(all=[2, 3, 4, 3, 4, 5, 4, 5, 6])

Applicative Builder

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

import java.util.*

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

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

ForNonEmptyList extensions {
 map(nelId, nelName, nelYear, { (id, name, year) ->
  Person(id, name, year)
// NonEmptyList(all=[Person(id=ff0fcee6-e707-4c0e-af2a-e7cca353e40c, name=William Alvin Howard, year=1926), Person(id=ff0fcee6-e707-4c0e-af2a-e7cca353e40c, name=Haskell Curry, year=1926), Person(id=36f386fb-2a07-42dd-8d29-a416d712a737, name=William Alvin Howard, year=1926), Person(id=36f386fb-2a07-42dd-8d29-a416d712a737, name=Haskell Curry, year=1926), Person(id=ff0fcee6-e707-4c0e-af2a-e7cca353e40c, name=William Alvin Howard, year=1900), Person(id=ff0fcee6-e707-4c0e-af2a-e7cca353e40c, name=Haskell Curry, year=1900), Person(id=36f386fb-2a07-42dd-8d29-a416d712a737, name=William Alvin Howard, year=1900), Person(id=36f386fb-2a07-42dd-8d29-a416d712a737, name=Haskell Curry, year=1900)])


  • NonEmptyList is used to model lists that guarantee at least one element
  • We can easily construct values of NonEmptyList with NonEmptyList.of
  • foldLeft, map, flatMap and others are used to compute over the internal contents of a NonEmptyList value.
  • NonEmptyList.monad().binding { ... } Comprehensions can be used to imperatively compute over multiple NonEmptyList values in sequence.
  • NonEmptyList.applicative().map { ... } can be used to compute over multiple NonEmptyList values preserving type information and abstracting over arity with map

Available Instances