pablisco
09/28/2021, 1:58 PMpublic sealed interface Either<out A, out B>
@JvmInline
public value class Left<out A>(public val value: A) : Either<A, Nothing>
@JvmInline
public value class Right<out B>(public val value: B) : Either<Nothing, B>
public sealed interface Either<out A, out B>
public interface Left<out A> : Either<A, Nothing> {
public val value: A
public companion object {
public operator fun <A> invoke(value: A): Left<A> = InternalLeft(InternalEither(value))
}
}
public interface Right<out B> : Either<Nothing, B> {
public val value: B
public companion object {
public operator fun <B> invoke(value: B): Right<B> = InternalRight<B>(InternalEither(value))
}
}
@JvmInline
public value class InternalEither internal constructor(internal val value: Any?)
@JvmInline
public value class InternalLeft<A> internal constructor(
private val internalEither: InternalEither,
) : Left<A> {
override val value: A
get() = internalEither.value as A
}
@JvmInline
public value class InternalRight<B> internal constructor(
private val internalEither: InternalEither,
) : Right<B> {
override val value: B
get() = internalEither.value as B
}
@JvmInline
value class Either<out A, out B> internal constructor(private val value: Any?) {
val left: A? get() = value as? A
val right: B? get() = value as? B
}
@Suppress("FunctionName") // constructor
fun <A> Left(value: A): Either<A, Nothing> = Either(value)
@Suppress("FunctionName") // constructor
fun <B> Right(value: B): Either<Nothing, B> = Either(value)
inline fun <A, B, C> Either<A, B>.fold(ifLeft: (A) -> C, ifRight: (B) -> C): C =
left?.let(ifLeft) ?: right?.let(ifRight) ?: error("WTF compiler?")
But, with this one we would loose the option to use when
expressions, which is a breaking change 🙃raulraja
09/28/2021, 2:27 PMpablisco
09/29/2021, 3:53 PM