Hello. I am trying to create an implementation of ...
# codereview
v
Hello. I am trying to create an implementation of a Result class. The difference compared to an existing Result class would be that the Success types are limited/constrained. Is there any way to let the compiler know that other success branches in
when
are unreachable?
Copy code
typealias MyResultCallback<T> = (MyResult<T>) -> Unit

sealed interface MyResult<out T : MyResult.Success<T>> {

    sealed interface Success<out T : Success<T>> : MyResult<T>

    @JvmInline
    value class Error(val throwable: Throwable) : MyResult<Nothing>

    fun interface Callback<T : Success<T>> {
        fun onResult(result: MyResult<T>)
    }
}

data class SuccessType1(val someJobTypeResult: String, val someJobTypeResult2: String) :
    MyResult.Success<SuccessType1>

data class SuccessType2(val someJobTypeResult: String, val someJobTypeResult3: String) :
    MyResult.Success<SuccessType2>

fun test() {
    val callback = MyResult.Callback<SuccessType1> { result ->
        when (result) {
            is MyResult.Error -> TODO()
            is SuccessType1 -> TODO()
            is SuccessType2 -> TODO("This is unreachable. How can I prevent having to add this?")
        }
    }
}
With this implementation, in the
test()
function, I actually get conflicting errors -- If I exclude the last branch, I'm told that the
when
is not exhaustive. If I do include it, I get an "Incompatible types" error message. I could use an
else
but ideally I shouldn't need to write any other branches, since the type has been explicitly declared as
MyResult.Callback<SuccessType1>