That seems not possible at the moment in the language.
However, we can move the NO_OP
out from the sealed hierarchies and use Coproduct
from the Arrow Library to define an ad-hoc sealed hierarchy:
import arrow.generic.coproduct2.Coproduct2
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
object NO_OP
typealias Operations = Coproduct2<NO_OP, Operation>
Or we can fix one of the type parameters in Coproduct
, and have:
typealias SomeThingWithNoOp<T> = Coproduct<NO_OP, T>
However, this is not ideal as it makes the hierarchy nested. With the top-level being Coproduct
, and the nested level being the customized hierarchy.
This may be addressed with Arrow-Meta's union type plugin in the near future.
Another way of seeing the problem is treating NO_OP
as the sentinel value. So we may encode NO_OP
as null or None
(From Arrow Option):
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
typealias Operations = Operation?
import arrow.core.Option
sealed class Operation {
class Add(val value: Int) : Operation()
class Substract(val value: Int) : Operation()
class Multiply(val value: Int) : Operation()
class Divide(val value: Int) : Operation()
}
typealias Operations = Option<Operation>
From my experience, encoding it as nullable may be easier to use, as Kotlin has the nullable type support built-in. While encoding it as Option
, Coproduct
or defining NO_OP
in each of the sealed hierarchies would make it more obvious(especially by using Coproduct
or NO_OP
in the sealed hierarchy).
Ref: