com.jnape.palatable.lambda.adt.coproduct

## Interface CoProduct3<A,B,C,CP3 extends CoProduct3<A,B,C,?>>

- Type Parameters:
    `A` - the first possible type
    `B` - the second possible type
    `C` - the third possible type
    `CP3` - the recursive type of this coproduct (used for embedding)
  All Known Implementing Classes:
    Choice3, These
  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 CoProduct3<A,B,C,CP3 extends CoProduct3<A,B,C,?>>

  A generalization of the coproduct of three types.
  See Also:
    `CoProduct2`

- - ### Method Summary

    All Methods Instance Methods Abstract Methods Default Methods
    Modifier and Type | Method and Description
    --- | ---
    `default CoProduct2<A,B,? extends CoProduct2<A,B,?>>` | `converge(Fn1<? super C,? extends CoProduct2<A,B,?>> convergenceFn)` Converge this coproduct down to a lower order coproduct by mapping the last possible type into an earlier possible type.
    `default <D> CoProduct4<A,B,C,D,? extends CoProduct4<A,B,C,D,?>>` | `diverge()` Diverge this coproduct by introducing another possible type that it could represent.
    `default <R> R` | `embed(Fn1<? super CP3,? extends R> aFn, Fn1<? super CP3,? extends R> bFn, Fn1<? super CP3,? extends R> cFn)` Embed this coproduct inside another value; that is, given morphisms from this coproduct to `R`, apply the appropriate morphism to this coproduct as a whole.
    `<R> R` | `match(Fn1<? super A,? extends R> aFn, Fn1<? super B,? extends R> bFn, Fn1<? super C,? extends R> cFn)` Type-safe convergence requiring a match against all potential types.
    `default Product3<Maybe<A>,Maybe<B>,Maybe<C>>` | `project()` Project this coproduct onto a product.
    `default Maybe<A>` | `projectA()` Convenience method for projecting this coproduct onto a product and then extracting the first slot value.
    `default Maybe<B>` | `projectB()` Convenience method for projecting this coproduct onto a product and then extracting the second slot value.
    `default Maybe<C>` | `projectC()` Convenience method for projecting this coproduct onto a product and then extracting the third slot value.

- - ### Method Detail

    - #### match

          <R> R match(Fn1<? super A,? extends R> aFn,
                      Fn1<? super B,? extends R> bFn,
                      Fn1<? super C,? extends R> cFn)

      Type-safe convergence requiring a match against all potential types.
      Type Parameters:
        `R` - result type
      Parameters:
        `aFn` - morphism `A -> R`
        `bFn` - morphism `B -> R`
        `cFn` - morphism `C -> R`
      Returns:
        the result of applying the appropriate morphism to this coproduct's unwrapped value
      See Also:
        `CoProduct2.match(Fn1, Fn1)`

    - #### diverge

          default <D> CoProduct4<A,B,C,D,? extends CoProduct4<A,B,C,D,?>> diverge()

      Diverge this coproduct by introducing another possible type that it could represent.
      Type Parameters:
        `D` - the additional possible type of this coproduct
      Returns:
        a `CoProduct4`<A, B, C, D>
      See Also:
        `CoProduct2.diverge()`

    - #### converge

          default CoProduct2<A,B,? extends CoProduct2<A,B,?>> converge(Fn1<? super C,? extends CoProduct2<A,B,?>> convergenceFn)

      Converge this coproduct down to a lower order coproduct by mapping the last possible type into an earlier possible type. This is the categorical dual of `CoProduct2.diverge()`, which introduces the type `C` and raises the order from 2 to 3.

      The following laws hold for any two coproducts of single order difference:

      - Cancellation: `coProductN.diverge().converge(CoProductN::a) == coProductN`
      Parameters:
        `convergenceFn` - function from last possible type to earlier type
      Returns:
        a `CoProduct2`<A, B>

    - #### project

          default Product3<Maybe<A>,Maybe<B>,Maybe<C>> project()

      Project this coproduct onto a product.
      Returns:
        a product of the coproduct projection
      See Also:
        `CoProduct2.project()`

    - #### projectA

          default Maybe<A> projectA()

      Convenience method for projecting this coproduct onto a product and then extracting the first slot value.
      Returns:
        an optional value representing the projection of the "a" type index

    - #### projectB

          default Maybe<B> projectB()

      Convenience method for projecting this coproduct onto a product and then extracting the second slot value.
      Returns:
        an optional value representing the projection of the "b" type index

    - #### projectC

          default Maybe<C> projectC()

      Convenience method for projecting this coproduct onto a product and then extracting the third slot value.
      Returns:
        an optional value representing the projection of the "c" type index

    - #### embed

          default <R> R embed(Fn1<? super CP3,? extends R> aFn,
                              Fn1<? super CP3,? extends R> bFn,
                              Fn1<? super CP3,? extends R> cFn)

      Embed this coproduct inside another value; that is, given morphisms from this coproduct to `R`, apply the appropriate morphism to this coproduct as a whole. Like `match(com.jnape.palatable.lambda.functions.Fn1<? super A, ? extends R>, com.jnape.palatable.lambda.functions.Fn1<? super B, ? extends R>, com.jnape.palatable.lambda.functions.Fn1<? super C, ? extends R>)`, but without unwrapping the value.
      Type Parameters:
        `R` - result type
      Parameters:
        `aFn` - morphism `A v B v C -> R`, applied in the `A` case
        `bFn` - morphism `A v B v C -> R`, applied in the `B` case
        `cFn` - morphism `A v B v C -> R`, applied in the `C` case
      Returns:
        the result of applying the appropriate morphism to this coproduct