An OptionalGetter is an optic that allows focusing on an optional value. It is an intermediate step between Fold, which focuses on 0 to N elements, and Getter, which focuses in exactly one element. Some people refer to OptionalGetters as AffineFolds.

The main function in OptionalGetter is getOrModify: (S) -> Either<S, A>, which allows us to get the focus OR return the original value, if the optic does not match. You can also use a version with getOption: (S) -> Option<A>, as exemplified in this optic to focus on the head of a list:

import arrow.core.*
import arrow.optics.*

val optionalHead: OptionalGetter<List<Int>, Int> = OptionalGetter(
    getOption = { list -> list.firstOrNull().toOption() }


The main use of OptionalGetter is to filter out unwanted elements. Here is an example in which we combine a Traversal focusing on every element in the list, with a filter to exclude those which are smaller than 0.

import arrow.optics.Traversal
import arrow.optics.Optional

val positiveNumbers = Traversal.list<Int>() compose OptionalGetter.filter { it >= 0 }

positiveNumbers.getAll(listOf(1, 2, -3, 4, -5)) == listOf(1, 2, 4)

Do you like Arrow?

Arrow Org