A `Fold`

is an optic that can see into a structure and get 0 to N foci.
It is a generalization of `fold`

, and implements all operators that can be derived from it.

A structure `S`

that has a focus `A`

to which we can apply a function `(A) -> R`

with `Monoid<R>`

to `S`

and get `R`

.
For example, `S == List<Int>`

to which we apply `(Int) -> String`

with `Monoid<String>`

and we get `R == String`

Creating a `Fold`

can be done by manually defining `foldMap`

.

```
import arrow.core.*
import arrow.optics.*
import arrow.typeclasses.*
fun <T> nullableFold(): Fold<T?, T> = object : Fold<T?, T> {
override fun <R> foldMap(M: Monoid<R>, s: T?, f: (T) -> R): R =
s?.let(f) ?: M.empty()
}
```

`Fold`

has an API similar to `kotlin.collections`

, but because it’s defined in terms of `foldMap`

, there are no associative fold functions available.

```
nullableFold<Int>().isEmpty(null)
```

```
Fold.nonEmptyList<Int>().combineAll(Monoid.int(), nonEmptyListOf(1, 2, 3))
```

```
nullableFold<Int>().firstOrNull(null)
```

```
Fold.nonEmptyList<Int>().firstOrNull(nonEmptyListOf(1, 2, 3, 4))
```

Composing `Fold`

can be used for accessing foci in nested structures.

```
val nestedNelFold: Fold<NonEmptyList<NonEmptyList<Int>>, NonEmptyList<Int>> = Fold.nonEmptyList()
val nestedNel = nonEmptyListOf(1, 2, 3, 4).map {
nonEmptyListOf(it, it)
}
(nestedNelFold compose Fold.nonEmptyList()).getAll(nestedNel)
```

`Fold`

can be composed with all optics except `Setter`

, and results in the following optics.

Iso | Lens | Prism | Optional | Getter | Setter | Fold | Traversal | |
---|---|---|---|---|---|---|---|---|

Fold | Fold | Fold | Fold | Fold | Fold | X | Fold | Fold |

Do you like Arrow?

✖