package com.jaytux.simd.frontend

import androidx.compose.runtime.Composable

sealed class Either<out L, out R> {
    class Left<L>(val value: L) : Either<L, Nothing>()
    class Right<R>(val value: R) : Either<Nothing, R>()

    fun <T> fold(onLeft: (L) -> T, onRight: (R) -> T): T = when(this) {
        is Left -> onLeft(value)
        is Right -> onRight(value)
    }

    suspend fun <T> foldSuspend(onLeft: suspend (L) -> T, onRight: suspend (R) -> T): T = when(this) {
        is Left -> onLeft(value)
        is Right -> onRight(value)
    }

    @Composable
    fun <T> foldCompose(onLeft: @Composable (L) -> T, onRight: @Composable (R) -> T): T = when(this) {
        is Left -> onLeft(value)
        is Right -> onRight(value)
    }
}

fun <T> T.left() = Either.Left(this)
fun <T> T.right() = Either.Right(this)

fun <L, R, X> Either<L, R>.map(f: (R) -> X): Either<L, X> = when(this) {
    is Either.Left -> this
    is Either.Right -> Either.Right(f(value))
}

typealias OrError<T> = Either<String, T>