I’m wanting to know if it’s possible to declare a sealed interface, and to then declare a sealed class that implements that interface that “re-aliases” the properties of the interface so that they have more domain-specific names.
E.g. I am doing the Either pattern from functional programming, but I want to make a subclass that uses terms other than the functional programming “left” and “right” names. This is for convenience.
Here’s my current attempt:
// Either.kt
sealed interface Either<A, B> {
open class Left<A, B>(open val left: A) : Either<A, B>
open class Right<A, B>(open val right: B) : Either<A, B>
}
// ContentEither.kt
sealed interface ContentEither<T> : Either<Throwable, T> {
data class Error<Throwable, T>(val error: Throwable) : Either.Left<Throwable, T>(error) {
override val left: Throwable = this.error
}
data class Content<E, T>(val content: T) : Either.Right<E, T>(content) {
override val right: T = this.content
}
}
The problem is, Error
is not known to implement ContentEither
so then I get errors like this when I try to use it
Type mismatch.
Required:
ContentEither<T>
Found:
ContentEither.Content<???, T>
If I try to say that it does implement ContentEither
, I then get this error:
sealed interface ContentEither<T> : Either<Throwable, T> {
data class Error<Throwable, T>(val error: Throwable) : Either.Left<Throwable, T>(error), ContentEither<T>() {
override val left: Throwable = this.error
}
data class Content<Throwable, T>(val content: T) : Either.Right<Throwable, T>(content), ContentEither<T> {
override val right: T = this.content
}
}
Type parameter A of 'Either' has inconsistent values: Throwable#1 (type parameter of org.me.ContentEither.Error), kotlin.Throwable
Is there a way to specify that these are the same Throwables? Is what I am trying to do possible in Kotlin?