Alex Vanyo

    Alex Vanyo

    1 year ago
    While experimenting with sealed interfaces and imagining how they might provide ways to model different hierarchies, I'm wondering if there's an opportunity to do some sort of smart casting or some sort of additional type resolution.
    sealed interface Alpha {
        interface A : Alpha
        interface B : Alpha
    }
    
    sealed class Beta /* : Alpha */ {
        object Y : Beta(), Alpha.A
        object Z : Beta(), Alpha.B
    }
    
    fun Beta.fix(): Alpha = when (this) {
        is Beta.Y -> this
        is Beta.Z -> this
    }
    
    fun first(beta: Beta) = second(beta.fix()) // Could fix() be implicit?
    
    fun second(alpha: Alpha) = when (alpha) {
        is Alpha.A -> "A"
        is Alpha.B -> "B"
    }
    All subclasses of
    Beta
    implement one of the subinterfaces of
    Alpha
    , so
    Beta is Alpha
    is always true. However,
    Beta
    can't directly implement
    Alpha
    without adding more subclasses to
    Alpha
    . It's possible to make this explicit with something like the
    Beta.fix()
    above, which shows that
    Beta is Alpha
    is always true, but it'd be really cool if that could be done automatically in some way.
    elizarov

    elizarov

    1 year ago
    I think that's KT-20297 Support exhaustive when for interfaces
    Alex Vanyo

    Alex Vanyo

    1 year ago
    They’re definitely related, but I’m wondering if it would be possible to do outside of when statements as well. For example, something like
    object Gamma {
        fun doSomethingWithAlpha(alpha: Alpha) {
            /* ... */
        }
    }
    
    fun third(beta: Beta) {
        Gamma.doSomethingWithAlpha(beta.fix()) // Could fix() be implicit?
    }
    This gets close to ideas around coercion, since
    fix()
    is explicitly showing that
    Beta is Alpha
    is always true.