40 lines
1.6 KiB
Kotlin
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!!
|