arrow-optics / arrow.optics / POptional

POptional

interface POptional<S, T, A, B> : POptionalOf<S, T, A, B>

Optional is an optic that allows to focus into a structure and querying or copy‘ing an optional focus.

import arrow.core.None
import arrow.core.Option
import arrow.core.Some
import arrow.optics.Optional

data class User(val username: String, val email: Option<String>) {
    companion object {
      // can be out generated by @optics
      val email: Optional<User, String> = Optional(User::email) { user, email ->
        user.copy(email = Some(email))
      }
  }
}

fun main(args: Array<String>) {
  val original = User("arrow-user", None)
  val set = User.email.set(original, "arRoW-UsEr@arrow-Kt.IO")
  val modified = User.email.modify(set, String::toLowerCase)
  println("original: $original, set: $set, modified: $modified")
}

A (polymorphic) POptional is useful when setting or modifying a value for a type with a optional polymorphic focus i.e. POptional<Either<Int, Double>, Either<String, Double>, Int, String>

A POptional can be seen as a weaker Lens and Prism and combines their weakest functions:

  • set: (S, B) -> T meaning we can focus into an S and set a value B for a target A and obtain a modified source T
  • getOrModify: (S) -> Either<T, A> meaning it returns the focus of a POptional OR the original value

Parameters

S - the source of a POptional

T - the modified source of a POptional

A - the focus of a POptional

B - the modified focus of a POptional

Functions

| all | Check if there is no focus or the target satisfies the predicate predicateopen fun all(source: S, predicate: (focus: A) -> Boolean): Boolean | | asFold | View a POptional as a Foldopen fun asFold(): Fold<S, A> | | asSetter | View a POptional as a PSetteropen fun asSetter(): PSetter<S, T, A, B> | | asTraversal | View a POptional as a PTraversalopen fun asTraversal(): PTraversal<S, T, A, B> | | choice | Join two POptional with the same focus Bopen infix fun <S1, T1> choice(other: POptional<S1, T1, A, B>): POptional<Either<S, S1>, Either<T, T1>, A, B> | | compose | Compose a POptional with a POptionalopen infix fun <C, D> compose(other: POptional<A, B, C, D>): POptional<S, T, C, D>
Compose a POptional with a PPrismopen infix fun <C, D> compose(other: PPrism<A, B, C, D>): POptional<S, T, C, D>
Compose a POptional with a PLensopen infix fun <C, D> compose(other: PLens<A, B, C, D>): POptional<S, T, C, D>
Compose a POptional with a PIsoopen infix fun <C, D> compose(other: PIso<A, B, C, D>): POptional<S, T, C, D>
open infix fun <C, D> compose(other: PSetter<A, B, C, D>): PSetter<S, T, C, D>
Compose a POptional with a Foldopen infix fun <C> compose(other: Fold<A, C>): Fold<S, C>
open infix fun <C> compose(other: Getter<A, C>): Fold<S, C>
Compose a POptional with a PTraversalopen infix fun <C, D> compose(other: PTraversal<A, B, C, D>): PTraversal<S, T, C, D> | | exists | Check if there is a focus and it satisfies the predicate predicateopen fun exists(source: S, predicate: (focus: A) -> Boolean): Boolean | | find | Find the focus that satisfies the predicate predicateopen fun find(source: S, predicate: (focus: A) -> Boolean): Option<A> | | first | Create a product of the POptional and a type Copen fun <C> first(): POptional<Tuple2<S, C>, Tuple2<T, C>, Tuple2<A, C>, Tuple2<B, C>> | | getOption | Get the focus of a POptional or Option.None if the is not thereopen fun getOption(source: S): Option<A> | | getOrModify | Get the focus of a POptional or return the original value while allowing the type to change if it does not matchabstract fun getOrModify(source: S): Either<T, A> | | isEmpty | Check if there is no focusopen fun isEmpty(source: S): Boolean | | lift | Lift a function f: (A) -> B to the context of S: (S) -> Topen fun lift(f: (focus: A) -> B): (S) -> T` | | [liftF](lift-f.html) | Lift a function [f](lift-f.html#arrow.optics.POptional$liftF(arrow.typeclasses.Applicative((arrow.optics.POptional.liftF.F)), kotlin.Function1((arrow.optics.POptional.A, arrow.Kind((arrow.optics.POptional.liftF.F, arrow.optics.POptional.B)))))/f): `(A) -> Kind<F, B> to the context of `S`: `(S) -&gt; Kind&lt;F, T&gt;open fun liftF(FA: Applicative, f: (focus: A) -> Kind<F, B>): (source: S) -> Kind<F, T>` | | [modify](modify.html) | Modify the focus of a [POptional](./index.html) with a function [f](modify.html#arrow.optics.POptional$modify(arrow.optics.POptional.S, kotlin.Function1((arrow.optics.POptional.A, arrow.optics.POptional.B)))/f)`open fun modify(source: S, f: (focus: A) -> B): T` | | [modifyF](modify-f.html) | Modify the focus of a [POptional](./index.html) with an Applicative function [f](modify-f.html#arrow.optics.POptional$modifyF(arrow.typeclasses.Applicative((arrow.optics.POptional.modifyF.F)), arrow.optics.POptional.S, kotlin.Function1((arrow.optics.POptional.A, arrow.Kind((arrow.optics.POptional.modifyF.F, arrow.optics.POptional.B)))))/f)`open fun modifyF(FA: Applicative, source: S, f: (focus: A) -> Kind<F, B>): Kind<F, T>` | | [modifyOption](modify-option.html) | Modify the focus of a [POptional](./index.html) with a function [f](modify-option.html#arrow.optics.POptional$modifyOption(arrow.optics.POptional.S, kotlin.Function1((arrow.optics.POptional.A, arrow.optics.POptional.B)))/f)`open fun modifyOption(source: S, f: (focus: A) -> B): Option` | | [nonEmpty](non-empty.html) | Check if there is a focus`open fun nonEmpty(source: S): `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) | | [plus](plus.html) | Plus operator overload to compose optionals`open operator fun <C, D> plus(other: `[`POptional`](./index.html)`<A, B, C, D>): `[`POptional`](./index.html)`<S, T, C, D>``open operator fun <C, D> plus(other: `[`PPrism`](../-p-prism/index.html)`<A, B, C, D>): `[`POptional`](./index.html)`<S, T, C, D>`
`open operator fun <C, D> plus(other: `[`PLens`](../-p-lens/index.html)`<A, B, C, D>): `[`POptional`](./index.html)`<S, T, C, D>`
`open operator fun <C, D> plus(other: `[`PIso`](../-p-iso/index.html)`<A, B, C, D>): `[`POptional`](./index.html)`<S, T, C, D>`
`open operator fun <C, D> plus(other: `[`PSetter`](../-p-setter/index.html)`<A, B, C, D>): `[`PSetter`](../-p-setter/index.html)`<S, T, C, D>`
`open operator fun plus(other: `[`Fold`](../-fold/index.html)`<A, C>): `[`Fold`](../-fold/index.html)`<S, C>`
`open operator fun plus(other: `[`Getter`](../-getter/index.html)`<A, C>): `[`Fold`](../-fold/index.html)`<S, C>`
`open operator fun <C, D> plus(other: `[`PTraversal`](../-p-traversal/index.html)`<A, B, C, D>): `[`PTraversal`](../-p-traversal/index.html)`<S, T, C, D>` | | [second](second.html) | Create a product of a type [C](second.html#C) and the [POptional](./index.html)`open fun second(): `[`POptional`](./index.html)`<Tuple2<C, S>, Tuple2<C, T>, Tuple2<C, A>, Tuple2<C, B>>` | | [set](set.html) | Get the modified source of a [POptional](./index.html)`abstract fun set(source: S, focus: B): T` | | [setOption](set-option.html) | Set the focus of a [POptional](./index.html) with a value.`open fun setOption(source: S, b: B): Option` |

Companion Object Functions

codiagonal POptional that takes either S or S and strips the choice of S.fun <S> codiagonal(): Optional<Either<S, S>, S>
id fun <S> id(): POptional<S, S, S, S>
invoke Invoke operator overload to create a POptional of type S with focus A. Can also be used to construct Optionaloperator fun <S, T, A, B> invoke(getOrModify: (source: S) -> Either<T, A>, set: (source: S, focus: B) -> T): POptional<S, T, A, B>
listHead Optional to safely operate on the head of a listfun <A> listHead(): Optional<List<A>, A>
listTail Optional to safely operate on the tail of a listfun <A> listTail(): Optional<List<A>, List<A>>
void POptional that never sees its focusfun <A, B> void(): Optional<A, B>

Extension Properties

some DSL to compose a Prism with focus arrow.core.Some with a Optional with a focus of Option<S>val <T, S> Optional<T, Option<S>>.some: Optional<T, S>

Extension Functions

at DSL to compose At with an Optional for a structure S to focus in on A at given index I.fun <T, S, I, A> Optional<T, S>.at(AT: At<S, I, A>, i: I): Optional<T, A>
every DSL to compose Each with an Optional for a structure S to see all its foci Afun <T, S, A> Optional<T, S>.~~every~~(EA: Each<S, A>): Traversal<T, A>
DSL to compose Traversal with an Optional for a structure S to see all its foci Afun <T, S, A> Optional<T, S>.every(TR: Traversal<S, A>): Traversal<T, A>
index DSL to compose Index with an Optional for a structure S to focus in on A at given index Ifun <T, S, I, A> Optional<T, S>.index(ID: Index<S, I, A>, i: I): Optional<T, A>

Do you like Arrow?

Arrow Org
<