ListK wraps over the platform List type to make it a type constructor.

It can be created from Kotlin List type with a convenient k() function.

import arrow.*

listOf(1, 2, 3).k()
// ListK(list=[1, 2, 3])

and unwrapped with the field list.

listOf(1, 2, 3).k().list
// [1, 2, 3]

ListK implements operators from many useful typeclasses.

For instance, it has combineK from the SemigroupK typeclass.

It can be used to cheaply combine two lists:

val hello = listOf('h', 'e', 'l', 'l', 'o').k()
val commaSpace = listOf(',', ' ').k()
val world = listOf('w', 'o', 'r', 'l', 'd').k()

// ListK(list=[h, e, l, l, o, ,,  , w, o, r, l, d])

The functions traverse and sequence come from Traverse.

Traversing a list creates a new container Kind<F, A> by combining the result of a function applied to each element:

import arrow.core.*
import arrow.instances.*

val numbers = listOf(Math.random(), Math.random(), Math.random()).k()
numbers.traverse(Option.applicative()) { if (it > 0.5) Some(it) else None }
// None

and complements the convenient function sequence() that converts a list of ListK<Kind<F, A>> into a Kind<F, ListK<A>>:

fun andAnother() = Some(Math.random())

val requests = listOf(Some(Math.random()), andAnother(), andAnother()).k()
// Some(ListK(list=[0.11375901583145565, 0.27974067095277255, 0.9161536243941971]))

If you want to aggregate the elements of a list into any other value you can use foldLeft and foldRight from Foldable.

Folding a list into a new value, String in this case, starting with an initial value and a combine function:

listOf('a', 'b', 'c', 'd', 'e').k().foldLeft("-> ") { x, y -> x + y }
// -> abcde

Or you can apply a list of transformations using ap from Applicative.

import arrow.instances.*
ForListK extensions {
  listOf(1, 2, 3).k()
    .ap(listOf({ x: Int -> x + 10}, { x: Int -> x * 2}).k())
// ListK(list=[11, 12, 13, 2, 4, 6])

Available Instances