Scripts/convention/src/main/kotlin/io/gitlab/jfronny/scripts/Either.kt

40 lines
1.6 KiB
Kotlin

package io.gitlab.jfronny.scripts
interface Either<L, R> {
val isLeft: Boolean
val isRight: Boolean
val left: L?
val right: R?
fun <U> mapLeft(f: (L) -> U): Either<U, R>
fun <U> mapRight(f: (R) -> U): Either<L, U>
fun <U> fold(l: (L) -> U, r: (R) -> U): U
fun foldLeft(f: (L) -> R): R
fun foldRight(f: (R) -> L): L
fun apply(l: (L) -> Unit, r: (R) -> Unit)
data class Left<L, R>(override val left: L) : Either<L, R> {
override val isLeft = true
override val isRight = false
override val right = null
override fun <U> mapLeft(f: (L) -> U): Either<U, R> = Left(f(left))
override fun <U> mapRight(f: (R) -> U): Either<L, U> = Left(left)
override fun <U> fold(l: (L) -> U, r: (R) -> U): U = l(left)
override fun foldRight(f: (R) -> L): L = left
override fun foldLeft(f: (L) -> R): R = f(left)
override fun apply(l: (L) -> Unit, r: (R) -> Unit) = l(left)
}
data class Right<L, R>(override val right: R) : Either<L, R> {
override val isLeft = false
override val isRight = true
override val left = null
override fun <U> mapLeft(f: (L) -> U): Either<U, R> = Right(right)
override fun <U> mapRight(f: (R) -> U): Either<L, U> = Right(f(right))
override fun <U> fold(l: (L) -> U, r: (R) -> U): U = r(right)
override fun foldRight(f: (R) -> L): L = f(right)
override fun foldLeft(f: (L) -> R): R = right
override fun apply(l: (L) -> Unit, r: (R) -> Unit) = r(right)
}
}
fun <T> Either<T, T>.fold(): T = if (isLeft) left!! else right!!