diff --git a/content/docs/learn/collections-functions/collectors.md b/content/docs/learn/collections-functions/collectors.md new file mode 100644 index 00000000..7733b617 --- /dev/null +++ b/content/docs/learn/collections-functions/collectors.md @@ -0,0 +1,61 @@ +--- +sidebar_position: 2 +description: Better aggregation over sequences +--- + +# Collectors + +Collectors help build complex computations over sequences of values, +guaranteeing that those values are consumed only once. + +Take for example the computation of the average of a list. You can +certainly write a simple version using the built-in functions, + + + +```kotlin +val average = list.sum() / list.size +``` + + +Note however that this implementation traverses the list _twice_, +one per operation over the list. This may not be a problem for small +lists but could become more problematic with longer collections. +Some data structures, like `Sequence` or `Flow`, impose an +even larger footprint, as their elements are computed every time +you need a new one. + +Collectors separate the description of the aggregation you want +to perform from the actual collection. To create a new collector +you use one of the built-in ones, and combine them using `zip`. + +```kotlin +import arrow.collectors.Collectors +import arrow.collectors.collect +import arrow.collectors.zip + +fun divide(x: Int, y: Int): Double = x.toDouble() / y.toDouble() + +val averageCollector = zip(Collectors.sum, Collectors.length, ::divide) +``` + + + +You then may apply the collector to the sequence or collection you want. + +```kotlin +val average = list.collect(averageCollector) +``` + + +:::note Influences + +The API implemented in `arrow-collectors` is heavily influenced by +Java's [`Collector`](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html) +and Haskell's [`foldl` library](https://hackage.haskell.org/package/foldl/docs/Control-Foldl.html). + +::: \ No newline at end of file diff --git a/content/docs/learn/collections-functions/memoize.md b/content/docs/learn/collections-functions/memoize.md index 208f74f6..6d03abb4 100644 --- a/content/docs/learn/collections-functions/memoize.md +++ b/content/docs/learn/collections-functions/memoize.md @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 description: Avoiding duplicate work for pure functions --- diff --git a/content/docs/learn/collections-functions/recursive.md b/content/docs/learn/collections-functions/recursive.md index c1e657c5..f78f4b3e 100644 --- a/content/docs/learn/collections-functions/recursive.md +++ b/content/docs/learn/collections-functions/recursive.md @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 3 description: Making functions stack-safe and efficient --- diff --git a/content/docs/learn/collections-functions/utils.md b/content/docs/learn/collections-functions/utils.md index 36ccf530..85528261 100644 --- a/content/docs/learn/collections-functions/utils.md +++ b/content/docs/learn/collections-functions/utils.md @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 5 description: Composition, partial application, and currying --- diff --git a/content/docs/learn/overview.md b/content/docs/learn/overview.md index 0d8034da..06455d99 100644 --- a/content/docs/learn/overview.md +++ b/content/docs/learn/overview.md @@ -39,7 +39,7 @@ Each section in the documentation roughly corresponds to one of the libraries th | `arrow-optics` + `arrow-optics-ksp-plugin`
_Companion to [data](https://kotlinlang.org/docs/data-classes.html) and [sealed](https://kotlinlang.org/docs/sealed-classes.html) classes_ | Utilities for [immutable data](../immutable-data/intro/) | | `arrow-fx-stm` | [Software Transactional Memory](../coroutines/stm/) (STM) | | `arrow-atomic`
_Multiplatform-ready [references](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.native.concurrent/-atomic-reference/)_ | [Atomic references](../coroutines/concurrency-primitives/#atomic) | -| `arrow-collectors`
_Kotlin-ready [collectors](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/package-summary.html)_ | Better aggregation over sequences | +| `arrow-collectors`
_Companion to [`fold`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html) and [`reduce`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html)_ | [Aggregation with single traversal](../collections-functions/collectors/) | | `arrow-eval`
_More powerful [laziness](https://kotlinlang.org/docs/delegated-properties.html#lazy-properties)_ | [Control over evaluation](../collections-functions/eval/) | | `arrow-functions`
Part of `arrow-core` in 1.x | [Utilities for functions](../collections-functions/utils/) | | `arrow-core-high-arity` | `arrow-core` for more than 10 parameters | diff --git a/guide/src/test/kotlin/examples/example-collectors-01.kt b/guide/src/test/kotlin/examples/example-collectors-01.kt new file mode 100644 index 00000000..d2719f03 --- /dev/null +++ b/guide/src/test/kotlin/examples/example-collectors-01.kt @@ -0,0 +1,6 @@ +// This file was automatically generated from collectors.md by Knit tool. Do not edit. +package arrow.website.examples.exampleCollectors01 + +val list = listOf(1, 2, 3) + +val average = list.sum() / list.size diff --git a/guide/src/test/kotlin/examples/example-collectors-02.kt b/guide/src/test/kotlin/examples/example-collectors-02.kt new file mode 100644 index 00000000..ed853d39 --- /dev/null +++ b/guide/src/test/kotlin/examples/example-collectors-02.kt @@ -0,0 +1,13 @@ +// This file was automatically generated from collectors.md by Knit tool. Do not edit. +package arrow.website.examples.exampleCollectors02 + +import arrow.collectors.Collectors +import arrow.collectors.collect +import arrow.collectors.zip + +fun divide(x: Int, y: Int): Double = x.toDouble() / y.toDouble() + +val averageCollector = zip(Collectors.sum, Collectors.length, ::divide) +val list = listOf(1, 2, 3) + +val average = list.collect(averageCollector)