Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-organize Optics docs #2583

Merged
merged 5 commits into from Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 11 additions & 4 deletions arrow-site/docs/_data/sidebar-optics.yml
Expand Up @@ -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/

Expand All @@ -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/

Expand Down
96 changes: 96 additions & 0 deletions 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<Employee>) {
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<Employee>()).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<Employee>().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<Int, String>) {
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<Int, String>().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<Employee>` by its index position or a `Map<K, V>` 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<Employee>().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<Employee>().run {
Employees.employees[2].company.address.street.name.getOrNull(employees)
}
```
91 changes: 1 addition & 90 deletions arrow-site/docs/docs/dsl/README.md
Expand Up @@ -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<Employee>) {
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<Employee>()).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<Employee>().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<Int, String>) {
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<Int, String>().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<Employee>` by its index position or a `Map<K, V>` 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<Employee>().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<Employee>().run {
Employees.employees[2].company.address.street.name.getOrNull(employees)
}
```
```