From 58af11fd5a7fcc3d62db32400fe5db780f565946 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 25 Nov 2021 14:50:58 +0100 Subject: [PATCH 1/3] Re-organize Optics docs --- arrow-site/docs/_data/sidebar-optics.yml | 15 +- .../docs/docs/collections_dsl/README.md | 96 +++++++ arrow-site/docs/docs/dsl/README.md | 91 +----- arrow-site/docs/docs/optics/README.md | 272 ++++++------------ 4 files changed, 189 insertions(+), 285 deletions(-) create mode 100644 arrow-site/docs/docs/collections_dsl/README.md diff --git a/arrow-site/docs/_data/sidebar-optics.yml b/arrow-site/docs/_data/sidebar-optics.yml index c7238299347..a7a0b0d2b44 100644 --- a/arrow-site/docs/_data/sidebar-optics.yml +++ b/arrow-site/docs/_data/sidebar-optics.yml @@ -2,13 +2,13 @@ options: - title: Quick Start url: /optics/ - - title: DSL - url: /optics/dsl/ - - - title: Types + - title: Values DSL nested_options: + - title: Overview + url: /optics/dsl/ + - title: Iso url: /optics/iso/ @@ -27,6 +27,13 @@ options: - title: Setter url: /optics/setter/ + - title: Collections DSL + + nested_options: + + - title: Overview + url: /optics/collections_dsl/ + - title: Fold url: /optics/fold/ diff --git a/arrow-site/docs/docs/collections_dsl/README.md b/arrow-site/docs/docs/collections_dsl/README.md new file mode 100644 index 00000000000..12bcccdedd4 --- /dev/null +++ b/arrow-site/docs/docs/collections_dsl/README.md @@ -0,0 +1,96 @@ +--- +layout: docs-optics +title: Syntax DSL +permalink: /optics/collections_dsl/ +--- + +## Optics DSL for Collections + +The Optics DSL has special support for optics that refer to elements in a collection. + +### [Every]({{ '/optics/every' | relative_url }}) + +`Every` can be used to focus into a structure `S` and see all its foci `A`. Here, we focus into all `Employee`s in the `Employees`. + +```kotlin +@optics data class Employees(val employees: List) { + companion object +} +``` + +```kotlin:ank +import arrow.optics.Every + +val jane = Employee("Jane Doe", Company("Kategory", Address("Functional city", Street(42, "lambda street")))) +val employees = Employees(listOf(john, jane)) + +Employees.employees.every(Every.list()).company.address.street.name.modify(employees, String::capitalize) +``` + +If you are in the scope of `Each`, you don't need to specify the instance. + +```kotlin:ank +Every.list().run { + Employees.employees.every.company.address.street.name.modify(employees, String::capitalize) +} +``` + +### [At]({{ '/optics/at' | relative_url }}) + +`At` can be used to focus in `A` at a given index `I` for a given structure `S`. + +```kotlin +@optics data class Db(val content: Map) { + companion object +} +``` + +Here we focus into the value of a given key in `MapK`. + +```kotlin:ank +import arrow.optics.typeclasses.At + +val db = Db(mapOf( + 1 to "one", + 2 to "two", + 3 to "three" +)) + +Db.content.at(At.map(), 2).some.modify(db, String::reversed) +``` + +If you are in the scope of `At`, you don't need to specify the instance. + +```kotlin:ank +At.map().run { + Db.content.at(2).some.modify(db, String::reversed) +} +``` + +### [Index]({{ '/optics/index' | relative_url }}) + +`Index` can be used to operate on a structure `S` that can index `A` by an index `I` (i.e., a `List` by its index position or a `Map` by its keys `K`). + + +```kotlin:ank +import arrow.optics.typeclasses.Index + +val updatedJohn = Employees.employees.index(Index.list(), 0).company.address.street.name.modify(employees, String::capitalize) +updatedJohn +``` + +In the scope of `Index`, you don't need to specify the instance, so we can enable `operator fun get` syntax. + +```kotlin:ank +Index.list().run { + Employees.employees[0].company.address.street.name.getOrNull(updatedJohn) +} +``` + +Since [Index]({{ '/optics/index' | relative_url }}) returns an [Optional]({{ '/optics/optional' | relative_url }}), `index` and `[]` are safe operations. + +```kotlin:ank +Index.list().run { + Employees.employees[2].company.address.street.name.getOrNull(employees) +} +``` diff --git a/arrow-site/docs/docs/dsl/README.md b/arrow-site/docs/docs/dsl/README.md index 4417190c15b..778aa7b7178 100644 --- a/arrow-site/docs/docs/dsl/README.md +++ b/arrow-site/docs/docs/dsl/README.md @@ -76,93 +76,4 @@ We can rewrite this code with our generated DSL. ```kotlin:ank NetworkResult.networkError.httpError.message.modify(networkResult, f) -``` - -The DSL also has special support for [Every]({{ '/optics/every' | relative_url }}), [At]({{ '/optics/at' | relative_url }}), [Index]({{ '/optics/index' | relative_url }}), etc. - -### Every - -`Every` can be used to focus into a structure `S` and see all its foci `A`. Here, we focus into all `Employee`s in the `Employees`. - -```kotlin -@optics data class Employees(val employees: List) { - companion object -} -``` - -```kotlin:ank -import arrow.optics.Every - -val jane = Employee("Jane Doe", Company("Kategory", Address("Functional city", Street(42, "lambda street")))) -val employees = Employees(listOf(john, jane)) - -Employees.employees.every(Every.list()).company.address.street.name.modify(employees, String::capitalize) -``` - -If you are in the scope of `Each`, you don't need to specify the instance. - -```kotlin:ank -Every.list().run { - Employees.employees.every.company.address.street.name.modify(employees, String::capitalize) -} -``` - -### At - -`At` can be used to focus in `A` at a given index `I` for a given structure `S`. - -```kotlin -@optics data class Db(val content: Map) { - companion object -} -``` - -Here we focus into the value of a given key in `MapK`. - -```kotlin:ank -import arrow.optics.typeclasses.At - -val db = Db(mapOf( - 1 to "one", - 2 to "two", - 3 to "three" -)) - -Db.content.at(At.map(), 2).some.modify(db, String::reversed) -``` - -If you are in the scope of `At`, you don't need to specify the instance. - -```kotlin:ank -At.map().run { - Db.content.at(2).some.modify(db, String::reversed) -} -``` - -### Index - -`Index` can be used to operate on a structure `S` that can index `A` by an index `I` (i.e., a `List` by its index position or a `Map` by its keys `K`). - - -```kotlin:ank -import arrow.optics.typeclasses.Index - -val updatedJohn = Employees.employees.index(Index.list(), 0).company.address.street.name.modify(employees, String::capitalize) -updatedJohn -``` - -In the scope of `Index`, you don't need to specify the instance, so we can enable `operator fun get` syntax. - -```kotlin:ank -Index.list().run { - Employees.employees[0].company.address.street.name.getOrNull(updatedJohn) -} -``` - -Since [Index]({{ '/optics/index' | relative_url }}) returns an [Optional]({{ '/optics/optional' | relative_url }}), `index` and `[]` are safe operations. - -```kotlin:ank -Index.list().run { - Employees.employees[2].company.address.street.name.getOrNull(employees) -} -``` +``` \ No newline at end of file diff --git a/arrow-site/docs/docs/optics/README.md b/arrow-site/docs/docs/optics/README.md index 14168efb178..8c79662b1cd 100644 --- a/arrow-site/docs/docs/optics/README.md +++ b/arrow-site/docs/docs/optics/README.md @@ -20,10 +20,20 @@ permalink: /optics/ Arrow Optics provides an automatic DSL that allows users to use `.` notation when accessing, composing, and transforming deeply nested immutable data structures. - Optics also offers all the base types such as [Lens]({{ "/optics/lens/" | relative_url }}), [Prism]( {{ '/optics/prism/' | relative_url }}), and others from which we can generalize accessing and -traversing deep values in sealed and data classes models.s +traversing deep values in sealed and data classes models. + +```kotlin +// an immutable value with very nested components +val john = Employee("John Doe", Company("Kategory", Address("Functional city", Street(42, "lambda street")))) +// an Optional points to one place in the value +val optional: Optional = Employee.company.address.street.name +// and now you can modify into a new copy without nested 'copy's! +optional.modify(john, String::toUpperCase) +``` + +Scroll down and learn what Arrow Optics can do for you(r code)!
@@ -33,37 +43,48 @@ traversing deep values in sealed and data classes models.s
#### Quick Start - - [Gradle Setup]({{ '/optics/#Gradle-kotlin' | relative_url }}) - - [Maven Setup]({{ '/optics/#Maven' | relative_url }}) + - [Gradle Setup]({{ '/optics/#setup' | relative_url }}) + - [Optics DSL]({{ '/optics/dsl/' | relative_url }}) + - [Optics DSL for Collections]({{ '/optics/collections_dsl/' | relative_url }})
-#### DSL - - [Optics DSL]({{ '/optics/dsl/' | relative_url }}) +#### Additional information +- [Kotlin Data classes](https://kotlinlang.org/docs/data-classes.html) +- [Kotlin Sealed classes](https://kotlinlang.org/docs/sealed-classes.html)
-#### Extensions and data types - - [Iso]({{ '/optics/iso/' | relative_url }}) - - [Lens]({{ '/optics/lens/' | relative_url }}) - - [Optional]({{ '/optics/optional/' | relative_url }}) - - [Prism]({{ '/optics/prims/' | relative_url }}) - - [Getter]({{ '/optics/getter/' | relative_url }}) - - [Setter]({{ '/optics/setter/' | relative_url }}) - - [Fold]({{ '/optics/fold/' | relative_url }}) - - [Traversal]({{ '/optics/traversal/' | relative_url }}) - - [Every]({{ '/optics/every/' | relative_url }}) - - [Cons]({{ '/optics/cons/' | relative_url }}) - - [Snoc]({{ '/optics/snoc/' | relative_url }}) - - [At]({{ '/optics/at/' | relative_url }}) - - [Index]({{ '/optics/index/' | relative_url }}) - - [FilterIndex]({{ '/optics/filterindex/' | relative_url }}) +#### [Optics DSL for Values]({{ '/optics/dsl/' | relative_url }}) + +###### Focus and modification + + - [Iso]({{ '/optics/iso/' | relative_url }}): 1-to-1 relations + - [Lens]({{ '/optics/lens/' | relative_url }}): focus and modify one value + - [Optional]({{ '/optics/optional/' | relative_url }}): optional value + +###### Single behavior + + - [Getter]({{ '/optics/getter/' | relative_url }}): focus on one value + - [Prism]({{ '/optics/prism/' | relative_url }}): focus on optional value + - [Setter]({{ '/optics/setter/' | relative_url }}): modify one value +
-#### Additional information - - [Kotlin Data classes](https://kotlinlang.org/docs/data-classes.html) - - [Kotlin Sealed classes](https://kotlinlang.org/docs/sealed-classes.html) +#### [Optics DSL for Collections]({{ '/optics/collections_dsl/' | relative_url }}) + +- [Every]({{ '/optics/every/' | relative_url }}): focus and modification +- [Fold]({{ '/optics/fold/' | relative_url }}): only focus +- [Traversal]({{ '/optics/traversal/' | relative_url }}): only modification + +###### Point to elements + +- [Cons]({{ '/optics/cons/' | relative_url }}) +- [Snoc]({{ '/optics/snoc/' | relative_url }}) +- [At]({{ '/optics/at/' | relative_url }}) +- [Index]({{ '/optics/index/' | relative_url }}) +- [FilterIndex]({{ '/optics/filterindex/' | relative_url }})
@@ -74,37 +95,20 @@ traversing deep values in sealed and data classes models.s -------------------------------------------------------------------------------- --> -
+
## Setup -{: .setup-subtitle} -Configure Arrow for your project -
-
-![Jdk](/img/quickstart/jdk-logo.svg "jdk") - -Make sure to have the latest version of JDK 1.8 installed. -
-
-![Android](/img/quickstart/android-logo.svg "android") - - -Arrow supports Android starting on API 21 and up. -
-
-
-
-#### Basic Setup +#### Step 1: add the repository In your project's root `build.gradle.kts`, append this repository to your list: @@ -116,20 +120,17 @@ allprojects { } ``` +#### Step 2: add the library + Add the dependencies into the project's `build.gradle.kts`: ``` -apply plugin: 'kotlin-kapt' - dependencies { implementation("io.arrow-kt:arrow-optics:1.0.1") - kapt("io.arrow-kt:arrow-meta:1.0.1") } ``` -#### BOM file - -To avoid specifying the Arrow version for every dependency, a BOM file is available: +If you are using more than one Arrow dependency, you can avoid specifying the same version over and over by using a BOM file: ``` dependencies { @@ -141,28 +142,30 @@ dependencies { } ``` -#### Next development version +#### Step 3: add the plug-in -If you want to try the latest features, replace `1.0.1` with `1.0.2-SNAPSHOT` and add this -configuration: +To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ``` -allprojects { - repositories { - ... - maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") - } - - // To use latest artifacts - configurations.all { resolutionStrategy.cacheChangingModulesFor(0, "seconds") } +buildscript { + repositories { + maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") + } + dependencies { + classpath("io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT") + } } + +apply(plugin = "io.arrow-kt.optics") ``` +Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})! +
-#### Basic Setup +#### Step 1: add the repository In your project's root `build.gradle`, append this repository to your list: @@ -174,24 +177,23 @@ allprojects { } ``` +#### Step 2: add the library + Add the dependencies into the project's `build.gradle`: ```groovy -apply plugin: 'kotlin-kapt' - def arrow_version = "1.0.1" + dependencies { implementation "io.arrow-kt:arrow-optics:$arrow_version" - kapt "io.arrow-kt:arrow-meta:$arrow_version" } ``` -#### BOM file - -To avoid specifying the Arrow version for every dependency, a BOM file is available: +If you are using more than one Arrow dependency, you can avoid specifying the same version over and over by using a BOM file: ```groovy def arrow_version = "1.0.1" + dependencies { implementation platform("io.arrow-kt:arrow-stack:$arrow_version") @@ -201,140 +203,28 @@ dependencies { } ``` -#### Next development version +#### Step 3: add the plug-in -If you want to try the latest features, replace `1.0.1` with `1.0.2-SNAPSHOT` and add this -configuration: +To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ```groovy -allprojects { - repositories { - ... - maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } - } - - // To use latest artifacts - configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } +buildscript { + repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + } + dependencies { + classpath 'io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT' + } } -``` - -
- -
- -#### Basic Setup -Make sure to have at least the latest version of JDK 1.8 installed. Add to your pom.xml file the -following properties: - -```xml - - - 1.5.31 - 1.0.1 - -``` - -Add the dependencies that you want to use: - -```xml - - - io.arrow-kt - arrow-core - ${arrow.version} - -``` - -#### Enabling kapt for the Optics DSL - -For the Optics DSL, enable annotation processing using Kotlin plugin: - -```xml - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - kapt - - kapt - - - - src/main/kotlin - - - - io.arrow-kt - arrow-meta - ${arrow.version} - - - - - - compile - compile - - compile - - - - src/main/kotlin - - - - - test-compile - test-compile - - test-compile - - - - -``` - -#### BOM file - -To avoid specifying the Arrow version for every dependency, a BOM file is available: - -```xml - - - - - io.arrow-kt - arrow-stack - ${arrow.version} - pom - import - - - -... - +apply plugin: 'io.arrow-kt.optics' ``` -#### Next development version - -If you want to try the latest features, replace `1.0.1` with `1.0.2-SNAPSHOT` and add this -configuration: +Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})! -```xml +
- - - https://oss.sonatype.org/content/repositories/snapshots/ - always - - -``` -
From ce48632d0a6d59efcd27e471e40ada698e4eca34 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 9 Dec 2021 15:52:26 +0100 Subject: [PATCH 2/3] Refer to KSP Optics plug-in --- arrow-site/docs/docs/optics/README.md | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/arrow-site/docs/docs/optics/README.md b/arrow-site/docs/docs/optics/README.md index 8c79662b1cd..073920a8882 100644 --- a/arrow-site/docs/docs/optics/README.md +++ b/arrow-site/docs/docs/optics/README.md @@ -147,16 +147,13 @@ dependencies { To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ``` -buildscript { - repositories { - maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") - } - dependencies { - classpath("io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT") - } +plugins { + id("com.google.devtools.ksp") version "1.6.0-1.0.1" } -apply(plugin = "io.arrow-kt.optics") +dependencies { + ksp("io.arrow-kt:arrow-optics-ksp:2.0-SNAPSHOT") +} ``` Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})! @@ -208,16 +205,13 @@ dependencies { To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ```groovy -buildscript { - repositories { - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } - } - dependencies { - classpath 'io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT' - } +plugins { + id "com.google.devtools.ksp" version "1.6.0-1.0.1" } -apply plugin: 'io.arrow-kt.optics' +dependencies { + ksp "io.arrow-kt:arrow-optics-ksp:2.0-SNAPSHOT" +} ``` Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})! From 092c1a1bd53a02fb39b2c24b8761ffee6f3bbe66 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Mon, 20 Dec 2021 10:58:34 +0100 Subject: [PATCH 3/3] Reverse KSP mention --- arrow-site/docs/docs/optics/README.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/arrow-site/docs/docs/optics/README.md b/arrow-site/docs/docs/optics/README.md index 073920a8882..8c79662b1cd 100644 --- a/arrow-site/docs/docs/optics/README.md +++ b/arrow-site/docs/docs/optics/README.md @@ -147,13 +147,16 @@ dependencies { To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ``` -plugins { - id("com.google.devtools.ksp") version "1.6.0-1.0.1" +buildscript { + repositories { + maven(url = "https://oss.sonatype.org/content/repositories/snapshots/") + } + dependencies { + classpath("io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT") + } } -dependencies { - ksp("io.arrow-kt:arrow-optics-ksp:2.0-SNAPSHOT") -} +apply(plugin = "io.arrow-kt.optics") ``` Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})! @@ -205,13 +208,16 @@ dependencies { To get the most of Arrow Optics you can add out Kotlin plug-in to your build, which takes care of generating optics for your data types. ```groovy -plugins { - id "com.google.devtools.ksp" version "1.6.0-1.0.1" +buildscript { + repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + } + dependencies { + classpath 'io.arrow-kt.optics:io.arrow-kt.optics.gradle.plugin:1.0-SNAPSHOT' + } } -dependencies { - ksp "io.arrow-kt:arrow-optics-ksp:2.0-SNAPSHOT" -} +apply plugin: 'io.arrow-kt.optics' ``` Now you are ready to learn about the [Optics DSL]({{ '/optics/dsl/' | relative_url }})!