https://kotlinlang.org logo
#android
Title
# android
m

mzgreen

01/19/2023, 7:45 AM
Hey folks, Kotlin has a
coerceAtLeast
function which is defined as:
fun <T : Comparable<T>> T.coerceAtLeast(minimumValue: T): T
So any type that is comparable can invoke this function, for example this works:
"foo".coerceAtLeast(...)
. I’ve created a similar function:
Copy code
fun interface Foo<in T> {
  fun foo()
}

fun <T : Foo<T>> T.bar() {}
but when I call it like this:
Copy code
val test = Foo<Int> {}
    test.bar()
it doesn’t work. It fails to compile with error:
Copy code
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public fun <T : Foo<TypeVariable(T)>> TypeVariable(T).bar(): Unit defined in root package in file File.kt
why is that? I don’t see any difference between this and
coerceAtLeast
. I can define more extensions on
Comparable
type and they work fine but my custom type doesn’t. It works only if I change:
fun <T : Foo<T>> T.bar() {}
to:
fun <T> Foo<T>.bar() {}
but these don’t have the exact same meaning and I still don’t get why the first one doesn’t work in the first place
t

Timo Gruen

01/19/2023, 7:55 AM
its not the same
fun <A, B : Foo<A>> B.bar() { }
would be the same to your
fun <A> Foo<A>.bar() { }
But you are using T twice, as the generic parameter of Foo and as a super type of Foo. Which doesnt make sense typically
m

mzgreen

01/19/2023, 7:57 AM
it does make sense and it’s typically used with comparable for example: https://stackoverflow.com/questions/8537500/java-the-meaning-of-t-extends-comparablet
c

CLOVIS

01/19/2023, 8:47 AM
@mzgreen it means comparable instances must be comparable of themselves.
Int
doesn't implement your
Foo
interface, so it's never possible for it to be
Foo
of itself.
m

mzgreen

01/19/2023, 8:51 AM
ahh yeah that’s right @CLOVIS, makes sense now, thanks!
just to close the topic, as Ivan explained, this works:
Copy code
class Test: Foo<Test> {
    override fun foo() {}
}

fun main() {
    val test = Test()
    test.bar()
}
👍 1
c

CLOVIS

01/19/2023, 9:00 AM
Multiple people have wanted to add this pattern of "extension interfaces", if you're curious here's a bit of reading: • Approach inspired by Haskell, proposed by the Arrow team : KEEP-87 | Discussion. For various reasons (in the discussion), it will not be added to Kotlin, but it's still very interesting to read. • The most likely solution to be implemented is KEEP-259 | Discussion. It's not exactly the same, but they took into consideration the KEEP-87 ideas and the solution seems very good to me. From what I've read, the Arrow team is happy with it too.
💯 1
m

mzgreen

01/19/2023, 9:01 AM
c

CLOVIS

01/19/2023, 9:02 AM
It's out-dated though, typeclasses won't be added to Kotlin.
m

mzgreen

01/19/2023, 9:04 AM
Yeah but it explains what the original keep 87 was about in simple words
95 Views