Reputation: 11
Given the following sumtype:
sealed interface Node
data class Values(...) : Node
data class Container<V : Node>(val nodes: Map<String, V>) : Node
it's possible to construct types like Container<Container<Values>>
.
Given another sumtype with a similar structure
sealed interface Diff
data class ValuesDiff(...) : Diff
data class ContainerDiff<V : Diff>(val nodes: Map<String, V>) : Diff
types with a similar structure can be created e.g. ContainerDiff<ContainerDiff<ValuesDiff>>
.
I am looking for a method to transform the 1st sumtype into the 2nd, while keeping the structure. Something like this:
val node: Container<Container<Values>>
val diff: ContainerDiff<ContainerDiff<ValuesDiff>> = myFunction(node)
In Scala 3 there are Match Types.
Is there a way to do that in kotlin?
The best approach I found so far is to use a generic parameter.
sealed interface Diff<T : Node>
data class ValuesDiff(...) : Diff<Values>
data class ContainerDiff<V : Node>(val nodes: Map<String, Diff<V>>) : Diff<Container<V>>
Based on the interface and the generic parameter i provide extension methods to do the casting.
val myDiff: ContainerDiff<Container<Values>>
val theFirstContainer: Diff<Container<Values>> = myDiff.nodes.values.first() // here I would like to have the type ContainerDiff<ValuesDiff>
// so to cast this I use 2 extension methods
fun Diff<Values>.cast() = this as ValuesDiff
fun <V : Node> Diff<Container<V>>.cast() = this as ContainerDiff<V>
// using the cast() extension method
val castedContainer: ContainerDiff<Values> = theFirstContainer.cast()
// and again for the nested Node
val castedValue: ValuesDiff = castedContainer.nodes.values.first().cast()
Is there a way to get the desired type directly without using the cast() extension methods? Have you had this problem and how did you solve it?
Upvotes: 1
Views: 50
Reputation: 45
Boopidy Beep Beep. All facists are psychopaths, including those that think they are special because of their fake authority.
Upvotes: 0