Skip to content

Commit d63b98d

Browse files
authored
Merge branch 'master' into SetKW_docs_Issue_324
2 parents 70df495 + 25ff3bf commit d63b98d

File tree

15 files changed

+283
-49
lines changed

15 files changed

+283
-49
lines changed

README.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,19 @@ Add the dependencies into the project's `build.gradle`
3838

3939
```groovy
4040
dependencies {
41-
compile 'io.arrow-kt:arrow-core:0.6.0'
42-
compile 'io.arrow-kt:arrow-typeclasses:0.6.0'
43-
compile 'io.arrow-kt:arrow-data:0.6.0'
44-
compile 'io.arrow-kt:arrow-instances:0.6.0'
45-
compile 'io.arrow-kt:arrow-syntax:0.6.0'
46-
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.0'
41+
compile 'io.arrow-kt:arrow-core:0.6.1'
42+
compile 'io.arrow-kt:arrow-typeclasses:0.6.1'
43+
compile 'io.arrow-kt:arrow-data:0.6.1'
44+
compile 'io.arrow-kt:arrow-instances:0.6.1'
45+
compile 'io.arrow-kt:arrow-syntax:0.6.1'
46+
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.1'
4747
48-
compile 'io.arrow-kt:arrow-free:0.6.0' //optional
49-
compile 'io.arrow-kt:arrow-mtl:0.6.0' //optional
50-
compile 'io.arrow-kt:arrow-effects:0.6.0' //optional
51-
compile 'io.arrow-kt:arrow-effects-rx2:0.6.0' //optional
52-
compile 'io.arrow-kt:arrow-effects-kotlinx-coroutines:0.6.0' //optional
53-
compile 'io.arrow-kt:arrow-optics:0.6.0' //optional
48+
compile 'io.arrow-kt:arrow-free:0.6.1' //optional
49+
compile 'io.arrow-kt:arrow-mtl:0.6.1' //optional
50+
compile 'io.arrow-kt:arrow-effects:0.6.1' //optional
51+
compile 'io.arrow-kt:arrow-effects-rx2:0.6.1' //optional
52+
compile 'io.arrow-kt:arrow-effects-kotlinx-coroutines:0.6.1' //optional
53+
compile 'io.arrow-kt:arrow-optics:0.6.1' //optional
5454
}
5555
```
5656

@@ -67,7 +67,7 @@ apply from: rootProject.file('gradle/generated-kotlin-sources.gradle') //optiona
6767
6868
dependencies {
6969
...
70-
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.0' //optional
70+
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.1' //optional
7171
...
7272
}
7373
```

ank-core/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ dependencies {
2222
kapt project(':arrow-annotations-processor')
2323
}
2424

25-
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
25+
//apply from: rootProject.file('gradle/gradle-mvn-push.gradle')

ank-gradle-plugin/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ gradlePlugin {
1515
}
1616
}
1717

18-
apply from: rootProject.file('gradle/gradle-mvn-push.gradle')
18+
//apply from: rootProject.file('gradle/gradle-mvn-push.gradle')

arrow-docs/docs/_data/menu.yml

+3
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ options:
248248
- title: FilterIndex
249249
url: /docs/optics/filterindex/
250250

251+
- title: Index
252+
url: /docs/optics/index/
253+
251254
- title: Integrations
252255

253256
nested_options:

arrow-docs/docs/docs/README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,18 @@ Add the dependencies into the project's `build.gradle`
4444

4545
```groovy
4646
dependencies {
47-
compile 'io.arrow-kt:arrow-core:0.6.0'
48-
compile 'io.arrow-kt:arrow-typeclasses:0.6.0'
49-
compile 'io.arrow-kt:arrow-instances:0.6.0'
50-
compile 'io.arrow-kt:arrow-syntax:0.6.0'
51-
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.0'
47+
compile 'io.arrow-kt:arrow-core:0.6.1'
48+
compile 'io.arrow-kt:arrow-typeclasses:0.6.1'
49+
compile 'io.arrow-kt:arrow-instances:0.6.1'
50+
compile 'io.arrow-kt:arrow-syntax:0.6.1'
51+
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.1'
5252
53-
compile 'io.arrow-kt:arrow-free:0.6.0' //optional
54-
compile 'io.arrow-kt:arrow-mtl:0.6.0' //optional
55-
compile 'io.arrow-kt:arrow-effects:0.6.0' //optional
56-
compile 'io.arrow-kt:arrow-effects-rx2:0.6.0' //optional
57-
compile 'io.arrow-kt:arrow-effects-kotlinx-coroutines:0.6.0' //optional
58-
compile 'io.arrow-kt:arrow-optics:0.6.0' //optional
53+
compile 'io.arrow-kt:arrow-free:0.6.1' //optional
54+
compile 'io.arrow-kt:arrow-mtl:0.6.1' //optional
55+
compile 'io.arrow-kt:arrow-effects:0.6.1' //optional
56+
compile 'io.arrow-kt:arrow-effects-rx2:0.6.1' //optional
57+
compile 'io.arrow-kt:arrow-effects-kotlinx-coroutines:0.6.1' //optional
58+
compile 'io.arrow-kt:arrow-optics:0.6.1' //optional
5959
}
6060
```
6161

@@ -72,7 +72,7 @@ apply from: rootProject.file('gradle/generated-kotlin-sources.gradle') //optiona
7272
7373
dependencies {
7474
...
75-
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.0' //optional
75+
kapt 'io.arrow-kt:arrow-annotations-processor:0.6.1' //optional
7676
...
7777
}
7878
```

arrow-docs/docs/docs/optics/filterindex/README.MD

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ permalink: /docs/optics/filterindex/
66

77
## FilterIndex
88

9-
`FilterIndex` provides a [Traversal]({{ '/docs/optics/traversal' | relative_url }}) that can see into a structure `S` and get, set or modify 0 to N foci whose index `I` satisfies a predicate.
9+
`FilterIndex` provides a [Traversal]({{ '/docs/optics/traversal' | relative_url }}) that can focus into a structure `S` and get, set or modify 0 to N foci whose index `I` satisfies a predicate.
1010

1111
If for a structure `S` the foci `A` can be indexed by `I` then a `Traversal` can be created by `FilterIndex` that is filtered by a predicate on `I`.
1212

@@ -33,7 +33,7 @@ val filter: Traversal<ListKWKind<String>, String> = filterIndexStringByIndex.fil
3333
filter.getAll(listOf("H", "He", "Hel", "Hell", "Hello").k())
3434
```
3535

36-
Arrow provides `FilterIndex` instances for some of its datatypes that can be filtered by index, like `ListKW` and `MapKW`. You can look them up by calling `FilterIndex.filterIndex()`.
36+
Arrow provides `FilterIndex` instances for some common datatypes both in Arrow and the Kotlin stdlib that can be filtered by index, like `ListKW` and `MapKW`. You can look them up by calling `FilterIndex.filterIndex()`.
3737

3838
```kotlin:ank
3939
FilterIndex.filterIndex<ListKWKind<Int>, Int, Int> { index -> index % 2 == 0 }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
layout: docs
3+
title: Index
4+
permalink: /docs/optics/index/
5+
---
6+
7+
## Index
8+
9+
`Index` provides an [Optional]({{ '/docs/optics/optional' | relative_url }}) for a structure `S` to focus in `A` at a given index `I`.
10+
11+
### Example
12+
13+
If for a structure `S` the focus `A` can be indexed by `I` then `Index` can create an `Optional` with focus at `S` for a given index `I`.
14+
We can use that `Optional` to safely operate on that focus `S` i.e. operating on items in a `List` based on the index position.
15+
16+
```kotlin:ank
17+
import arrow.data.*
18+
import arrow.optics.typeclasses.*
19+
20+
val thirdListItemOptional = Index.index<ListKWKind<String>, Int, String>(3)
21+
22+
thirdListItemOptional.set(listOf("0", "1", "2", "3").k(), "newValue")
23+
```
24+
```kotlin:ank
25+
thirdListItemOptional.set(listOf("0", "1", "2").k(), "newValue")
26+
```
27+
```kotlin:ank
28+
thirdListItemOptional.setOption(listOf("0", "1", "2").k(), "newValue")
29+
```
30+
31+
#### Creating your own `Index` instances
32+
33+
Arrow provides `Index` instances for some common datatypes both in Arrow and the Kotlin stdlib that can be indexed, like `ListKW` and `MapKW`.
34+
You can look them up by calling `Index.index()`.
35+
36+
You may create instances of `Index` for your own datatypes which you will be able to use as demonstrated in the [example](#example) above.
37+
38+
See [Deriving and creating custom typeclass]({{ '/docs/patterns/glossary' | relative_url }}) to provide your own `Index` instances for custom datatypes.
39+
40+
### Instances
41+
42+
The following datatypes in Arrow provide instances that adhere to the `Index` typeclass.
43+
44+
- [String]
45+
- [NonEmptyList]({{ '/docs/datatypes/nonemptylist' | relative_url }})
46+
- [ListKW]({{ '/docs/datatypes/listkw' | relative_url }})
47+
- [SequenceKW]({{ '/docs/datatypes/sequencekw' | relative_url }})
48+
- [MapKW]({{ '/docs/datatypes/mapkw' | relative_url }})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package arrow.optics.instances
2+
3+
import arrow.data.ListKW
4+
import arrow.data.ListKWKind
5+
import arrow.data.MapKW
6+
import arrow.data.MapKWKind
7+
import arrow.data.NonEmptyList
8+
import arrow.data.NonEmptyListKind
9+
import arrow.data.SequenceKW
10+
import arrow.data.SequenceKWKind
11+
import arrow.data.ev
12+
import arrow.data.k
13+
import arrow.instance
14+
import arrow.optics.Optional
15+
import arrow.optics.POptional
16+
import arrow.optics.listToListKW
17+
import arrow.optics.stringToList
18+
import arrow.optics.typeclasses.Index
19+
import arrow.optics.typeclasses.index
20+
import arrow.syntax.either.left
21+
import arrow.syntax.either.right
22+
23+
@instance(ListKW::class)
24+
interface ListKWIndexInstance<A> : Index<ListKWKind<A>, Int, A> {
25+
override fun index(i: Int): Optional<ListKWKind<A>, A> = POptional(
26+
getOrModify = { it.ev().getOrNull(i)?.right() ?: it.ev().left() },
27+
set = { a -> { l -> l.ev().mapIndexed { index: Int, aa: A -> if (index == i) a else aa }.k() } }
28+
)
29+
}
30+
31+
@instance(MapKW::class)
32+
interface MapKWIndexInstance<K, V> : Index<MapKWKind<K, V>, K, V> {
33+
override fun index(i: K): Optional<MapKWKind<K, V>, V> = POptional(
34+
getOrModify = { it.ev()[i]?.right() ?: it.left() },
35+
set = { v -> { m -> m.ev().mapValues { (k, vv) -> if (k == i) v else vv }.k() } }
36+
)
37+
}
38+
39+
@instance(SequenceKW::class)
40+
interface SequenceKWIndexInstance<A> : Index<SequenceKWKind<A>, Int, A> {
41+
override fun index(i: Int): Optional<SequenceKWKind<A>, A> = POptional(
42+
getOrModify = { it.ev().sequence.elementAtOrNull(i)?.right() ?: it.ev().left() },
43+
set = { a -> { it.ev().mapIndexed { index, aa -> if (index == i) a else aa }.k() } }
44+
)
45+
}
46+
47+
object StringIndexInstance : Index<String, Int, Char> {
48+
49+
override fun index(i: Int): Optional<String, Char> =
50+
stringToList compose listToListKW() compose index<ListKW<Char>, Int, Char>().index(i)
51+
}
52+
53+
object StringIndexInstanceImplicits {
54+
@JvmStatic
55+
fun instance(): StringIndexInstance = StringIndexInstance
56+
}
57+
58+
@instance(NonEmptyList::class)
59+
interface NonEmptyListIndexInstance<A> : Index<NonEmptyListKind<A>, Int, A> {
60+
61+
override fun index(i: Int): Optional<NonEmptyListKind<A>, A> = POptional(
62+
getOrModify = { l ->
63+
l.ev().all.getOrNull(i)?.right() ?: l.ev().left()
64+
},
65+
set = { a ->
66+
{ l ->
67+
NonEmptyList.fromListUnsafe(
68+
l.ev().all.mapIndexed { index: Int, aa: A -> if (index == i) a else aa }
69+
)
70+
}
71+
}
72+
)
73+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package java_lang
2+
3+
import arrow.optics.instances.StringIndexInstance
4+
5+
object StringIndexInstanceImplicits {
6+
@JvmStatic
7+
fun instance(): StringIndexInstance = StringIndexInstance
8+
}

arrow-optics/src/main/kotlin/arrow/optics/std/list.kt

-10
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import arrow.core.*
44
import arrow.data.ListKW
55
import arrow.data.NonEmptyList
66
import arrow.data.k
7-
import arrow.syntax.either.left
8-
import arrow.syntax.either.right
97

108
/**
119
* [Optional] to safely operate on the head of a list
@@ -16,14 +14,6 @@ fun <A> listHead(): Optional<List<A>, A> = Optional(
1614
set = { newHead -> { list -> list.mapIndexed { index, value -> if (index == 0) newHead else value } } }
1715
)
1816

19-
/**
20-
* [Optional] to safely operate on a certain index of a list
21-
*/
22-
fun <A> listElementPositionOptional(position: Int): Optional<List<A>, A> = Optional(
23-
getOrModify = { l -> l.getOrNull(position)?.right() ?: l.left() },
24-
set = { e -> { l -> l.mapIndexed { index: Int, value: A -> if (index == position) e else value } } }
25-
)
26-
2717
/**
2818
* [Optional] to safely operate on the tail of a list
2919
*/

arrow-optics/src/main/kotlin/arrow/optics/typeclasses/FilterIndex.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import arrow.typeclasses.Applicative
1111
import arrow.typeclasses.Traverse
1212

1313
/**
14-
* [FilterIndex] provides a [Traversal] that can be for a structure [S] with all its foci [A] whose index [I] satisfies a predicate.
14+
* [FilterIndex] provides a [Traversal] for a structure [S] with all its foci [A] whose index [I] satisfies a predicate.
1515
*
1616
* @param S source of [Traversal]
1717
* @param I index that uniquely identifies every focus of the [Traversal]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package arrow.optics.typeclasses
2+
3+
import arrow.TC
4+
import arrow.optics.Iso
5+
import arrow.optics.Optional
6+
import arrow.typeclass
7+
8+
/**
9+
* [Index] provides an [Optional] for a structure [S] to focus in [A] at a given index [I].
10+
*
11+
* @param S source of [Optional]
12+
* @param I index
13+
* @param A target of [Optional], [A] is supposed to be unique for a given pair [S] and [I].
14+
*/
15+
@typeclass
16+
interface Index<S, I, A> : TC {
17+
18+
/**
19+
* Get the focus [A] for a structure [S] at index [i].
20+
*/
21+
fun index(i: I): Optional<S, A>
22+
23+
companion object {
24+
25+
/**
26+
* Lift an instance of [Index] using an [Iso].
27+
*/
28+
fun <S, A, I , B> fromIso(ID: Index<A, I, B>, iso: Iso<S, A>): Index<S, I, B> = object : Index<S, I, B> {
29+
override fun index(i: I): Optional<S, B> = iso compose ID.index(i)
30+
}
31+
32+
/**
33+
* Get an [Optional] for an index [i] given an [Index].
34+
*/
35+
fun <S, I, A> index(ID: Index<S, I, A>, i: I): Optional<S, A> = ID.index(i)
36+
37+
}
38+
39+
}
40+
41+
/**
42+
* Lift an instance of [Index] using an [Iso].
43+
*/
44+
inline fun <reified S, reified A, reified I, reified B> Index.Companion.fromIso(iso: Iso<S, A>, ID: Index<A, I, B> = arrow.optics.typeclasses.index()): Index<S, I, B> = Index.fromIso(ID, iso)
45+
46+
/**
47+
* Get an [Optional] for an index [i] given an [Index].
48+
*/
49+
inline fun <reified S, reified I, reified A> Index.Companion.index(i: I, ID: Index<S, I, A> = arrow.optics.typeclasses.index()): Optional<S, A> = ID.index(i)

arrow-optics/src/test/kotlin/arrow/optics/OptionalTest.kt

-8
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,6 @@ class OptionalTest : UnitSpec() {
2525

2626
init {
2727

28-
testLaws(OptionalLaws.laws(
29-
optional = listElementPositionOptional(50),
30-
aGen = Gen.list(Gen.int()),
31-
bGen = Gen.int(),
32-
funcGen = genFunctionAToB(Gen.int()),
33-
EQA = Eq.any(),
34-
EQOptionB = Eq.any()))
35-
3628
testLaws(OptionalLaws.laws(
3729
optional = nullableOptional(),
3830
aGen = genNullable(Gen.int()),

0 commit comments

Comments
 (0)