com.jnape.palatable.lambda.optics

## Interface Iso<S,T,A,B>

- Type Parameters:
    `S` - the larger type for focusing
    `T` - the larger type for mirrored focusing
    `A` - the smaller type for focusing
    `B` - the smaller type for mirrored focusing
  All Superinterfaces:
    Applicative<T,Iso<S,?,A,B>>, Contravariant<S,Profunctor<?,T,Iso<?,?,A,B>>>, Functor<T,Iso<S,?,A,B>>, Monad<T,Iso<S,?,A,B>>, MonadRec<T,Iso<S,?,A,B>>, Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>, Profunctor<S,T,Iso<?,?,A,B>>
  All Known Subinterfaces:
    Iso.Simple<S,A>, TypeSafeKey<A,B>, TypeSafeKey.Simple<A>
  Functional Interface:
    This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.

      @FunctionalInterface
      public interface Iso<S,T,A,B>
      extends Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>, MonadRec<T,Iso<S,?,A,B>>, Profunctor<S,T,Iso<?,?,A,B>>

  An `Iso` (short for "isomorphism") is an invertible `Lens`: an `Optic` encoding of a bi-directional focusing of two types, and like ``Lens`es`, can be ``View`ed`, `Set`, and ``updated``.

  As an example, consider the isomorphism between valid `String`s and `Integer`s:

       Iso<String, String, Integer, Integer> stringIntIso = Iso.iso(Integer::parseInt, Object::toString);
       Integer asInt = view(stringIntIso, "123"); // 123
       String asString = view(stringIntIso.mirror(), 123); // "123"

  In the previous example, `stringIntIso` can be viewed as an ``Optic`<String, String, Integer, Integer>`, and can be ``mirror()`ed` and viewed as a ``Optic`<Integer, Integer, String, String>`.

  As with `Lens`, variance is supported between `S/T` and `A/B`, and where these pairs do not vary, a `Iso.Simple` iso can be used (for instance, in the previous example, `stringIntIso` could have had the simplified `Iso.Simple<String, Integer>` type).

  For more information, read about isos.

  See Also:
    `Optic`, `Lens`

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Interface and Description
    --- | ---
    `static interface` | `Iso.Simple<S,A>` A convenience type with a simplified type signature for common isos with both unified "larger" values and unified "smaller" values.

  - ### Method Summary

    All Methods Static Methods Instance Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `default <Z,C> Iso<S,T,Z,C>` | `andThen(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,A,B,Z,C> f)` Left-to-right composition of optics.
    `default <R,U> Iso<R,U,A,B>` | `compose(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,R,U,S,T> g)` Right-to-Left composition of optics.
    `default <R> Iso<R,T,A,B>` | `contraMap(Fn1<? super R,? extends S> fn)` Contravariantly map `A <- B`.
    `default <R,U> Iso<R,U,A,B>` | `diMap(Fn1<? super R,? extends S> lFn, Fn1<? super T,? extends U> rFn)` Dually map contravariantly over the left parameter and covariantly over the right parameter.
    `default <R> Iso<R,T,A,B>` | `diMapL(Fn1<? super R,? extends S> fn)` Contravariantly map over the left parameter.
    `default <U> Iso<S,U,A,B>` | `diMapR(Fn1<? super T,? extends U> fn)` Covariantly map over the right parameter.
    `default <U> Iso<S,U,A,B>` | `discardL(Applicative<U,Iso<S,?,A,B>> appB)` Sequence both this `Applicative` and `appB`, discarding this `Applicative's` result and returning `appB`.
    `default <U> Iso<S,T,A,B>` | `discardR(Applicative<U,Iso<S,?,A,B>> appB)` Sequence both this `Applicative` and `appB`, discarding `appB's` result and returning this `Applicative`.
    `default <U> Iso<S,U,A,B>` | `flatMap(Fn1<? super T,? extends Monad<U,Iso<S,?,A,B>>> fn)` Chain dependent computations that may continue or short-circuit based on previous results.
    `default <U> Iso<S,U,A,B>` | `fmap(Fn1<? super T,? extends U> fn)` Covariantly transmute this functor's parameter using the given mapping function.
    `static <S,T,A,B> Iso<S,T,A,B>` | `iso(Fn1<? super S,? extends A> f, Fn1<? super B,? extends T> g)` Static factory method for creating an iso from a function and it's inverse.
    `static <S,T,A,B> Iso<S,T,A,B>` | `iso(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,S,T,A,B> optic)` Promote an optic with compatible bounds to an `Iso`.
    `default <C> Iso<S,T,C,B>` | `mapA(Fn1<? super A,? extends C> fn)` Covariantly map `A` to `C`, yielding a new optic.
    `default <Z> Iso<S,T,A,Z>` | `mapB(Fn1<? super Z,? extends B> fn)` Contravariantly map `B` to `Z`, yielding a new optic.
    `default <R> Iso<R,T,A,B>` | `mapS(Fn1<? super R,? extends S> fn)` Contravariantly map `S` to `R`, yielding a new optic.
    `default <U> Iso<S,U,A,B>` | `mapT(Fn1<? super T,? extends U> fn)` Covariantly map `T` to `U`, yielding a new optic.
    `default Iso<B,A,T,S>` | `mirror()` Flip this `Iso` around.
    `default <U> Iso<S,U,A,B>` | `pure(U u)` Lift the value `b` into this applicative functor.
    `static <S,A,B> Pure<Iso<S,?,A,B>>` | `pureIso(Fn1<? super S,? extends A> sa)` The canonical `Pure` instance for `Iso`.
    `static <S,A> Iso.Simple<S,A>` | `simpleIso(Fn1<? super S,? extends A> f, Fn1<? super A,? extends S> g)` Static factory method for creating a simple `Iso` from a function and its inverse.
    `default Lens<S,T,A,B>` | `toLens()` Convert this `Iso` into a `Lens`.
    `default <U> Iso<S,U,A,B>` | `trampolineM(Fn1<? super T,? extends MonadRec<RecursiveResult<T,U>,Iso<S,?,A,B>>> fn)` Given some operation yielding a `RecursiveResult` inside this `MonadRec`, internally trampoline the operation until it yields a `termination` instruction.
    `default Tuple2<Fn1<? super S,? extends A>,Fn1<? super B,? extends T>>` | `unIso()` Destructure this `Iso` into the two functions `S -< A` and `B -< T` that constitute the isomorphism.
    `default <U> Iso<S,U,A,B>` | `zip(Applicative<Fn1<? super T,? extends U>,Iso<S,?,A,B>> appFn)` Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.

    - ### Methods inherited from interface com.jnape.palatable.lambda.optics.Optic

      `apply, monomorphize, optic, reframe`

    - ### Methods inherited from interface com.jnape.palatable.lambda.monad.MonadRec

      `lazyZip`

    - ### Methods inherited from interface com.jnape.palatable.lambda.monad.Monad

      `join`

    - ### Methods inherited from interface com.jnape.palatable.lambda.functor.Functor

      `coerce`

- - ### Method Detail

    - #### toLens

          default Lens<S,T,A,B> toLens()

      Convert this `Iso` into a `Lens`.
      Returns:
        the equivalent lens

    - #### mirror

          default Iso<B,A,T,S> mirror()

      Flip this `Iso` around.
      Returns:
        the mirrored `Iso`

    - #### unIso

          default Tuple2<Fn1<? super S,? extends A>,Fn1<? super B,? extends T>> unIso()

      Destructure this `Iso` into the two functions `S -< A` and `B -< T` that constitute the isomorphism.
      Returns:
        the destructured iso

    - #### fmap

          default <U> Iso<S,U,A,B> fmap(Fn1<? super T,? extends U> fn)

      Covariantly transmute this functor's parameter using the given mapping function. Generally this method is specialized to return an instance of the class implementing Functor.
      Specified by:
        `fmap` in interface `Applicative<T,Iso<S,?,A,B>>`
      Specified by:
        `fmap` in interface `Functor<T,Iso<S,?,A,B>>`
      Specified by:
        `fmap` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `fmap` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the new parameter type
      Parameters:
        `fn` - the mapping function
      Returns:
        a functor over B (the new parameter type)

    - #### pure

          default <U> Iso<S,U,A,B> pure(U u)

      Lift the value `b` into this applicative functor.
      Specified by:
        `pure` in interface `Applicative<T,Iso<S,?,A,B>>`
      Specified by:
        `pure` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `pure` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the type of the returned applicative's parameter
      Parameters:
        `u` - the value
      Returns:
        an instance of this applicative over b

    - #### zip

          default <U> Iso<S,U,A,B> zip(Applicative<Fn1<? super T,? extends U>,Iso<S,?,A,B>> appFn)

      Given another instance of this applicative over a mapping function, "zip" the two instances together using whatever application semantics the current applicative supports.
      Specified by:
        `zip` in interface `Applicative<T,Iso<S,?,A,B>>`
      Specified by:
        `zip` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `zip` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the resulting applicative parameter type
      Parameters:
        `appFn` - the other applicative instance
      Returns:
        the mapped applicative

    - #### discardL

          default <U> Iso<S,U,A,B> discardL(Applicative<U,Iso<S,?,A,B>> appB)

      Sequence both this `Applicative` and `appB`, discarding this `Applicative's` result and returning `appB`. This is generally useful for sequentially performing side-effects.
      Specified by:
        `discardL` in interface `Applicative<T,Iso<S,?,A,B>>`
      Specified by:
        `discardL` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `discardL` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the type of the returned Applicative's parameter
      Parameters:
        `appB` - the other Applicative
      Returns:
        appB

    - #### discardR

          default <U> Iso<S,T,A,B> discardR(Applicative<U,Iso<S,?,A,B>> appB)

      Sequence both this `Applicative` and `appB`, discarding `appB's` result and returning this `Applicative`. This is generally useful for sequentially performing side-effects.
      Specified by:
        `discardR` in interface `Applicative<T,Iso<S,?,A,B>>`
      Specified by:
        `discardR` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `discardR` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the type of appB's parameter
      Parameters:
        `appB` - the other Applicative
      Returns:
        this Applicative

    - #### flatMap

          default <U> Iso<S,U,A,B> flatMap(Fn1<? super T,? extends Monad<U,Iso<S,?,A,B>>> fn)

      Chain dependent computations that may continue or short-circuit based on previous results.
      Specified by:
        `flatMap` in interface `Monad<T,Iso<S,?,A,B>>`
      Specified by:
        `flatMap` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the resulting monad parameter type
      Parameters:
        `fn` - the dependent computation over A
      Returns:
        the new monad instance

    - #### trampolineM

          default <U> Iso<S,U,A,B> trampolineM(Fn1<? super T,? extends MonadRec<RecursiveResult<T,U>,Iso<S,?,A,B>>> fn)

      Given some operation yielding a `RecursiveResult` inside this `MonadRec`, internally trampoline the operation until it yields a `termination` instruction.

      Stack-safety depends on implementations guaranteeing that the growth of the call stack is a constant factor independent of the number of invocations of the operation. For various examples of how this can be achieved in stereotypical circumstances, see the referenced types.

      Specified by:
        `trampolineM` in interface `MonadRec<T,Iso<S,?,A,B>>`
      Type Parameters:
        `U` - the ultimate resulting carrier type
      Parameters:
        `fn` - the function to internally trampoline
      Returns:
        the trampolined `MonadRec`
      See Also:
        `for a basic implementation`, `for a {@link CoProduct2 coproduct} implementation`, `for an implementation leveraging an already stack-safe {@link Monad#flatMap(Fn1)}`, `for a {@link MonadT monad transformer} implementation`

    - #### diMapL

          default <R> Iso<R,T,A,B> diMapL(Fn1<? super R,? extends S> fn)

      Contravariantly map over the left parameter.
      Specified by:
        `diMapL` in interface `Profunctor<S,T,Iso<?,?,A,B>>`
      Type Parameters:
        `R` - the new left parameter type
      Parameters:
        `fn` - the mapping function
      Returns:
        a profunctor over Z (the new left parameter type) and C (the same right parameter type)

    - #### diMapR

          default <U> Iso<S,U,A,B> diMapR(Fn1<? super T,? extends U> fn)

      Covariantly map over the right parameter. For all profunctors that are also functors, it should hold that `diMapR(f) == fmap(f)`.
      Specified by:
        `diMapR` in interface `Profunctor<S,T,Iso<?,?,A,B>>`
      Type Parameters:
        `U` - the new right parameter type
      Parameters:
        `fn` - the mapping function
      Returns:
        a profunctor over A (the same left parameter type) and C (the new right parameter type)

    - #### diMap

          default <R,U> Iso<R,U,A,B> diMap(Fn1<? super R,? extends S> lFn,
                                           Fn1<? super T,? extends U> rFn)

      Dually map contravariantly over the left parameter and covariantly over the right parameter. This is isomorphic to `diMapL(lFn).diMapR(rFn)`.
      Specified by:
        `diMap` in interface `Profunctor<S,T,Iso<?,?,A,B>>`
      Type Parameters:
        `R` - the new left parameter type
        `U` - the new right parameter type
      Parameters:
        `lFn` - the left parameter mapping function
        `rFn` - the right parameter mapping function
      Returns:
        a profunctor over Z (the new left parameter type) and C (the new right parameter type)

    - #### contraMap

          default <R> Iso<R,T,A,B> contraMap(Fn1<? super R,? extends S> fn)

      Contravariantly map `A <- B`.
      Specified by:
        `contraMap` in interface `Contravariant<S,Profunctor<?,T,Iso<?,?,A,B>>>`
      Specified by:
        `contraMap` in interface `Profunctor<S,T,Iso<?,?,A,B>>`
      Type Parameters:
        `R` - the new parameter type
      Parameters:
        `fn` - the mapping function
      Returns:
        the mapped Contravariant functor instance

    - #### mapS

          default <R> Iso<R,T,A,B> mapS(Fn1<? super R,? extends S> fn)

      Contravariantly map `S` to `R`, yielding a new optic.
      Specified by:
        `mapS` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `R` - the new left side of the output profunctor
      Parameters:
        `fn` - the mapping function
      Returns:
        the new optic

    - #### mapT

          default <U> Iso<S,U,A,B> mapT(Fn1<? super T,? extends U> fn)

      Covariantly map `T` to `U`, yielding a new optic.
      Specified by:
        `mapT` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `U` - the new right side's functor embedding of the output profunctor
      Parameters:
        `fn` - the mapping function
      Returns:
        the new optic

    - #### mapA

          default <C> Iso<S,T,C,B> mapA(Fn1<? super A,? extends C> fn)

      Covariantly map `A` to `C`, yielding a new optic.
      Specified by:
        `mapA` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `C` - the new left side of the input profunctor
      Parameters:
        `fn` - the mapping function
      Returns:
        the new optic

    - #### mapB

          default <Z> Iso<S,T,A,Z> mapB(Fn1<? super Z,? extends B> fn)

      Contravariantly map `B` to `Z`, yielding a new optic.
      Specified by:
        `mapB` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `Z` - the new right side's functor embedding of the input profunctor
      Parameters:
        `fn` - the mapping function
      Returns:
        the new optic

    - #### andThen

          default <Z,C> Iso<S,T,Z,C> andThen(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,A,B,Z,C> f)

      Left-to-right composition of optics. Requires compatibility between `S` and `T`.
      Specified by:
        `andThen` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `Z` - the new left side of the input profunctor
        `C` - the new right side's functor embedding of the input profunctor
      Parameters:
        `f` - the other optic
      Returns:
        the composed optic

    - #### compose

          default <R,U> Iso<R,U,A,B> compose(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,R,U,S,T> g)

      Right-to-Left composition of optics. Requires compatibility between `A` and `B`.
      Specified by:
        `compose` in interface `Optic<Profunctor<?,?,?>,Functor<?,?>,S,T,A,B>`
      Type Parameters:
        `R` - the new left side of the output profunctor
        `U` - the new right side's functor embedding of the output profunctor
      Parameters:
        `g` - the other optic
      Returns:
        the composed optic

    - #### iso

          static <S,T,A,B> Iso<S,T,A,B> iso(Fn1<? super S,? extends A> f,
                                            Fn1<? super B,? extends T> g)

      Static factory method for creating an iso from a function and it's inverse.
      Type Parameters:
        `S` - the larger type for focusing
        `T` - the larger type for mirrored focusing
        `A` - the smaller type for focusing
        `B` - the smaller type for mirrored focusing
      Parameters:
        `f` - the function
        `g` - f's inverse
      Returns:
        the iso

    - #### iso

          static <S,T,A,B> Iso<S,T,A,B> iso(Optic<? super Profunctor<?,?,?>,? super Functor<?,?>,S,T,A,B> optic)

      Promote an optic with compatible bounds to an `Iso`.
      Type Parameters:
        `S` - the larger type for focusing
        `T` - the larger type for mirrored focusing
        `A` - the smaller type for focusing
        `B` - the smaller type for mirrored focusing
      Parameters:
        `optic` - the `Optic`
      Returns:
        the `Iso`

    - #### simpleIso

          static <S,A> Iso.Simple<S,A> simpleIso(Fn1<? super S,? extends A> f,
                                                 Fn1<? super A,? extends S> g)

      Static factory method for creating a simple `Iso` from a function and its inverse.
      Type Parameters:
        `S` - one side of the isomorphism
        `A` - the other side of the isomorphism
      Parameters:
        `f` - a function
        `g` - f's inverse
      Returns:
        the simple iso

    - #### pureIso

          static <S,A,B> Pure<Iso<S,?,A,B>> pureIso(Fn1<? super S,? extends A> sa)

      The canonical `Pure` instance for `Iso`.
      Type Parameters:
        `S` - the larger type for focusing
        `A` - the smaller type for focusing
        `B` - the smaller type for mirrored focusing
      Parameters:
        `sa` - one side of the isomorphism
      Returns:
        the `Pure` instance