<@U5RSSGVKM> Im not sure what your use case is bu...
# sofl-user-group
m
@protomike Im not sure what your use case is but you might benefit from separating sub class specific logic from the parent sealed class
Copy code
sealed class Result<T, E> {
    abstract val value: T
    abstract val error: E
    abstract val isOk: Boolean
    val isError:Boolean get() = isOk

    @Suppress("UNCHECKED_CAST")
    inline infix fun <U> map(f: (T) -> (U)): Result<U, E> = when (this) {
        is Ok<T, E> -> Ok<U, E>(f(this.v))
        is Error<T, E> -> this as Error<U, E>
    }

    @Suppress("UNCHECKED_CAST")
    inline infix fun <U> mapErr(f: (E) -> (U)): Result<T, U> = when (this) {
        is Ok<T, E> -> this as Ok<T, U>
        is Error<T, E> -> Error<T, U>(f(this.e))
    }

    // MONAD

    @Suppress("UNCHECKED_CAST")
    inline infix fun <U> flatMap(f: (T) -> (Result<U, E>)): Result<U, E> = when (this) {
        is Ok<T, E> -> f(this.v)
        is Error<T, E> -> this as Error<U, E>
    }

    @Suppress("UNCHECKED_CAST")
    inline infix fun <U> flatMapErr(f: (E) -> (Result<T, U>)): Result<T, U> = when (this) {
        is Ok<T, E> -> this as Ok<T, U>
        is Error<T, E> -> f(this.e)
    }
}


data class Ok<T, E>(override val value: T) : Result<T, E>() {
    override val error: E get() = throw RuntimeException("attempt to get error of ${this}")
    override val isOk    = true
}

data class Error<T, E>(override val error: E) : Result<T, E>() {    
    override val value: T get() = throw RuntimeException("attempt to get value of ${this}")
    override val isOk    = false    
}