run.smt.ktest.util.functional.Either.Either.kt Maven / Gradle / Ivy
package run.smt.ktest.util.functional.Either
import run.smt.ktest.util.functional.identity
fun left(left: A): Either = Left(left)
fun right(right: B): Either = Right(right)
sealed class Either {
abstract val left: A?
abstract val right: B?
abstract val isRight: Boolean
abstract val flip: Either
val isLeft: Boolean = !isRight
inline fun bimap(leftMapper: (A) -> AA, rightMapper: (B) -> BB): Either
= if (isLeft) left(leftMapper(left!!)) else right(rightMapper(right!!))
inline fun mapLeft(mapper: (A) -> AA): Either = bimap(mapper, identity())
inline fun mapRight(mapper: (B) -> BB): Either = bimap(identity(), mapper)
inline fun unify(leftMapper: (A) -> C, rightMapper: (B) -> C): C
= if (isRight) rightMapper(right!!) else leftMapper(left!!)
}
private class Left(override val left: A) : Either() {
override val right: B? = null
override val isRight: Boolean = false
override val flip: Either by lazy { Right(left) }
}
private class Right(override val right: B) : Either() {
override val left: A? = null
override val isRight: Boolean = true
override val flip: Either by lazy { Left(right) }
}