-
Notifications
You must be signed in to change notification settings - Fork 437
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
208 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
layout: docs | ||
title: Cons | ||
permalink: /docs/optics/cons/ | ||
--- | ||
|
||
## Cons | ||
|
||
{:.beginner} | ||
beginner | ||
|
||
`Cons` provides a [Prism]({{ '/docs/optics/prism' | relative_url }}) between a structure `S` and its first element `A` and tail `S`. | ||
It provides a convenient way to attach or detach elements to the beginning side of a structure [S]. | ||
|
||
It can be constructed by providing the `Prism`. | ||
|
||
```kotlin:ank | ||
import arrow.data.ListK | ||
import arrow.optics.instances.listk.cons.cons | ||
import arrow.optics.typeclasses.Cons | ||
val listFirst = ListK.cons<Int>().cons() | ||
val instance = Cons(listFirst) | ||
instance | ||
``` | ||
|
||
It defines two functions `cons` and `uncons`. | ||
|
||
`cons` prepends an element `A` to a structure `S`. | ||
|
||
```kotlin:ank | ||
import arrow.optics.instances.list.cons.cons | ||
1.cons(listOf(2, 3)) | ||
``` | ||
|
||
`uncons` detaches the first element `A` from a structure `S`. | ||
|
||
```kotlin:ank | ||
import arrow.optics.instances.list.cons.uncons | ||
listOf(1, 2, 3).uncons() | ||
``` | ||
```kotlin:ank | ||
emptyList<Int>().uncons() | ||
``` | ||
|
||
### Data types | ||
|
||
```kotlin:ank:replace | ||
import arrow.reflect.* | ||
import arrow.optics.typeclasses.* | ||
TypeClass(Cons::class).dtMarkdownList() | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
modules/optics/arrow-optics/src/main/kotlin/arrow/optics/typeclasses/Cons.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package arrow.optics.typeclasses | ||
|
||
import arrow.core.* | ||
import arrow.optics.* | ||
|
||
/** | ||
* [Cons] provides a [Prism] between [S] and its first element [A] and tail [S]. | ||
* It provides a convenient way to attach or detach elements to the left side of a structure [S]. | ||
* | ||
* @param S source of [Prism] and tail of [Prism] focus. | ||
* @param A first element of [Prism] focus, [A] is supposed to be unique for a given [S]. | ||
*/ | ||
interface Cons<S, A> { | ||
|
||
/** | ||
* Provides a [Prism] between [S] and its first element [A] and tail [S]. | ||
*/ | ||
fun cons(): Prism<S, Tuple2<A, S>> | ||
|
||
/** | ||
* Provides an [Optional] between [S] and its first element [A]. | ||
*/ | ||
fun firstOption(): Optional<S, A> = | ||
cons() compose Tuple2.first() | ||
|
||
/** | ||
* Provides an [Optional] between [S] and its tail [S]. | ||
*/ | ||
fun tailOption(): Optional<S, S> = | ||
cons() compose Tuple2.second() | ||
|
||
/** | ||
* Prepend an element [A] to the first element of [S]. | ||
* | ||
* @receiver [A] element to prepend or attach on left side of [tail]. | ||
*/ | ||
infix fun A.cons(tail: S): S = | ||
cons().reverseGet(Tuple2(this, tail)) | ||
|
||
/** | ||
* Deconstruct an [S] to its optional first element [A] and tail [S]. | ||
* | ||
* @receiver [S] structure to uncons into its first element [A] and tail [S]. | ||
*/ | ||
fun S.uncons(): Option<Tuple2<A, S>> = | ||
cons().getOption(this) | ||
|
||
companion object { | ||
|
||
/** | ||
* Lift an instance of [Cons] using an [Iso]. | ||
*/ | ||
fun <S, A, B> fromIso(C: Cons<A, B>, iso: Iso<S, A>): Cons<S, B> = object : Cons<S, B> { | ||
override fun cons(): Prism<S, Tuple2<B, S>> = iso compose C.cons() compose iso.reverse().second() | ||
} | ||
|
||
operator fun <S, A> invoke(prism: Prism<S, Tuple2<A, S>>): Cons<S, A> = object : Cons<S, A> { | ||
override fun cons(): Prism<S, Tuple2<A, S>> = prism | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters