Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin generic constraint with "any of" rather than "all of"

Question: Is there a way to constraint a generic type in Kotlin in a way that it can be a disjunction of a list of types, or "whatever has function foo", rather than a conjunction of the constraints?

where T:Type1, T:Type2<Foo>

means that T must comply with Type1 and Type2

But what if, for example, I want to extend Math with sqr, that operates on built in numeric types:

fun <T> Math.sqr(op:T): T 
    where T:Int or Long or Float or Double = op * op

or even on anything that has * or times:

fun <T> Math.sqr(op:T): T
    where T: can do times // like "responds to selector" in Obj-C
    = op.times(op)

Anything like that? The latter is cooler because T can be a "Complex" or vectors with "*" defined as their inner product... just imagine and implement.

Theoretically, I could have invented a set of "primitives" that inherit from "Math-able" but that's quite ugly because it means I need to use my own set of vars.

interface Mathable {
    fun plus(m:Mathable)
    fun minus(m:Mathable)
    fun times(m:Mathable)
    fun div(m:Mathable)
}

class Int2 : Number, Comparable<Int2>, Mathable

It's just as ugly (relatively speaking, of course...) as

inline fun <reified T:Number> sqr(n:T):T {
    return where n {
        is Int -> n * n
        is Float -> n * n
        is Whatever -> n * n
        ....
        else -> throw SomeException("huh?!")
    }
}

Is there a better/cooler way?

Update: Checking the Kotlin class Int code, makes me doubt. They just did it with overloading. Still, nice to know if that's possible.

Thanks

like image 241
Maneki Neko Avatar asked Sep 14 '25 14:09

Maneki Neko


1 Answers

Unfortunately, the answer is:

  1. No, currently there isn't.

  2. Type classes proposal (or something similar) will fix it, if accepted (something like Mathable will be a type class).

  3. even on anything that has * or times

    This is called structural types and I don't think anything similar is planned for Kotlin.

like image 91
Alexey Romanov Avatar answered Sep 17 '25 20:09

Alexey Romanov