All Downloads are FREE. Search and download functionalities are using the official Maven repository.

arrow.generic.coproduct4.Coproduct4.kt Maven / Gradle / Ivy

package arrow.generic.coproduct4

import arrow.core.Option
import arrow.core.toOption
import kotlin.Suppress
import kotlin.Unit

/**
 * Represents a sealed hierarchy of 4 types where only one of the types is actually present.
 */
sealed class Coproduct4

/**
 * Represents the first type of a Coproduct4
 */
data class First(val a: A) : Coproduct4()

/**
 * Represents the second type of a Coproduct4
 */
data class Second(val b: B) : Coproduct4()

/**
 * Represents the third type of a Coproduct4
 */
data class Third(val c: C) : Coproduct4()

/**
 * Represents the fourth type of a Coproduct4
 */
data class Fourth(val d: D) : Coproduct4()

/**
 * Creates a Coproduct from the A type
 *
 * @return A Coproduct4 where the receiver is the A
 */
fun  A.first(): Coproduct4 = First(this)

/**
 * Creates a Coproduct from the B type
 *
 * @return A Coproduct4 where the receiver is the B
 */
fun  B.second(): Coproduct4 = Second(this)

/**
 * Creates a Coproduct from the C type
 *
 * @return A Coproduct4 where the receiver is the C
 */
fun  C.third(): Coproduct4 = Third(this)

/**
 * Creates a Coproduct from the D type
 *
 * @return A Coproduct4 where the receiver is the D
 */
fun  D.fourth(): Coproduct4 = Fourth(this)

/**
 * Transforms the Coproduct into an Option based on the actual value of the Coproduct
 *
 * @return None if the Coproduct was not the specified type, Some if it was the specified type
 */
fun  Coproduct4.select(): Option = (this as? First)?.a.toOption()

/**
 * Transforms the Coproduct into an Option based on the actual value of the Coproduct
 *
 * @return None if the Coproduct was not the specified type, Some if it was the specified type
 */
@Suppress("UNUSED_PARAMETER")
fun  Coproduct4<*, B, *, *>.select(dummy0: Unit = Unit): Option = (this as?
        Second)?.b.toOption()

/**
 * Transforms the Coproduct into an Option based on the actual value of the Coproduct
 *
 * @return None if the Coproduct was not the specified type, Some if it was the specified type
 */
@Suppress("UNUSED_PARAMETER")
fun  Coproduct4<*, *, C, *>.select(dummy0: Unit = Unit, dummy1: Unit = Unit): Option = (this
        as? Third)?.c.toOption()

/**
 * Transforms the Coproduct into an Option based on the actual value of the Coproduct
 *
 * @return None if the Coproduct was not the specified type, Some if it was the specified type
 */
@Suppress("UNUSED_PARAMETER")
fun  Coproduct4<*, *, *, D>.select(
    dummy0: Unit = Unit,
    dummy1: Unit = Unit,
    dummy2: Unit = Unit
): Option = (this as? Fourth)?.d.toOption()

/**
 * Runs the function related to the actual value of the Coproduct and returns the result
 *
 * @param a The function used to map A to the RESULT type
 * @param b The function used to map B to the RESULT type
 * @param c The function used to map C to the RESULT type
 * @param d The function used to map D to the RESULT type
 *
 * @return RESULT generated by one of the input functions
 */
fun  Coproduct4.fold(
    a: (A) -> RESULT,
    b: (B) -> RESULT,
    c: (C) -> RESULT,
    d: (D) -> RESULT
): RESULT = when (this) {
    is First -> a(this.a)
    is Second -> b(this.b)
    is Third -> c(this.c)
    is Fourth -> d(this.d)
}