Problem with types

It’s hard to describe that problem with words, so I’ll just send an example
ˋˋˋkt
interface A
interface B
interface C

class X: A, B
class Y: A, B, C

fun f(p: X)
fun f(p: Y)
ˋˋˋ
The behaviour of both definitions of ˋfˋ is exactly the same. ˋfˋ should take in any type that implements A and B.
but this is very bad obviously.
The only solution to that problem:
ˋˋˋkt
interface AB: A, B

class X: AB
class Y: AB, C

fun f(p: AB)
ˋˋˋ
This works perfectly fine, but you can’t always do that. If you can’t modify the declaration of ˋXˋ (if it is in a library for example), then you are going to have problems. The only solution to that problem is to add syntax specifically for that.
Example:
ˋˋˋ
class X: A, B
class Y: A, B, C

fun f(p: A | B)
ˋˋˋ
With this, one could also do: ˋtypealias AB = A | Bˋ.
Also not sure if ˋA | Bˋ is the best syntax for that.
Maybe ˋA + Bˋ or ˋA & Bˋ is better?

In your case, you could write:

fun <T> f(p: T) where T: A, T: B { /*...*/ }
3 Likes

Oh I didn’t know that’s a thing
thanks!

The workaround with generic type and where clause works, but the feature you are looking for is called intersection types.

It currently exists in the compiler itself (eg. it can infer that expression if(foo) 1 else 0f returns an intersection type of Number and Comparable),
is available in limited way in written code in form of definitely non-nullable types,
and hopefully will be implemented sometime after kotlin 2.0

1 Like