package io.gitlab.jfronny.scripts interface Either { val isLeft: Boolean val isRight: Boolean val left: L? val right: R? fun mapLeft(f: (L) -> U): Either fun mapRight(f: (R) -> U): Either fun 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(override val left: L) : Either { override val isLeft = true override val isRight = false override val right = null override fun mapLeft(f: (L) -> U): Either = Left(f(left)) override fun mapRight(f: (R) -> U): Either = Left(left) override fun 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(override val right: R) : Either { override val isLeft = false override val isRight = true override val left = null override fun mapLeft(f: (L) -> U): Either = Right(right) override fun mapRight(f: (R) -> U): Either = Right(f(right)) override fun 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 Either.fold(): T = if (isLeft) left!! else right!!