Szymon Jeziorski
11/11/2022, 7:40 PMpublic inline fun <R, T : R> Result<T>.getOrElse(onFailure: (exception: Throwable) -> R): R
From the signature I would think that since T is of type R or its subtype, on Result<SubClass> instance I could invoke getOrElse only by passing lambda returning value of type which is super type to SubClass.
Below code compiles perfectly fine, and I'm not sure why:
val x: Result<CharSequence> = runCatching { "string value" }
val z = x.getOrElse { 123 }
it would be logical for me that only lambdas returning super type of CharSequence should be accepted, but I can pass whatever return type I want and this still works fine, it just makes inferred type of z Result<Any>. Am I missing something or should this not be expected behavior? Also, I cannot understand reason behind T : R within function's declaration, if anything R : T would be more logical to my understanding.ephemient
11/11/2022, 7:44 PMclass Result<out T>, a Result<CharSequence> is a Result<Any>Szymon Jeziorski
11/11/2022, 7:53 PMfun <R, T : R> genericFunction(first: T, second: R): R = second
open class BaseClass(val name: String)
class SubClass(val secondName: String, name: String) : BaseClass(name)
val base = BaseClass("name")
val derived = SubClass("secondName", "name")
val firstCall = genericFunction(base, derived) // inferred type is BaseClass
val secondCall = genericFunction(derived, base) // inferred type is BaseClass
val thirdCall = genericFunction(base, "string") // inferred type is Any
it would be logical for me that third call shouldn't be possible as BaseClass is not a subtype of String
Could you advice further?ephemient
11/11/2022, 7:55 PMgenericFunction<Any, BaseClass>(). there's no reason the compiler needs to choose the narrowest possible type for each generic parameter in isolation - in fact, in many cases it must not. instead, it tries to find the narrowest type that satisfies the expression.Szymon Jeziorski
11/11/2022, 7:57 PM