eygraber
02/22/2024, 4:38 AMk as C
, especially since I got an error when I tried lookup[C::class] = factory
despite C
being guaranteed to be a K
. Anyone know why I didn't get a warning?
public class FooFactory<K : FooKey> {
@PublishedApi internal val lookup: MutableMap<KClass<out K>, (K) -> Foo<out K>> = mutableMapOf()
public inline fun <reified C : K> addFactory(
noinline factory: (C) -> Foo<out C>
) {
lookup[C::class] = { k ->
factory(k as C)
}
}
}
dmitriy.novozhilov
02/22/2024, 5:48 AMC
is reified
parameter, so it will be inlined to specific type argument on each call site, which makes this cast not uncheckedeygraber
02/22/2024, 5:51 AMk
parameter to the lambda is typed as K
? So if C
was FooKey.Bar
wouldn't the cast be k: K as FooKey.Bar
?dmitriy.novozhilov
02/22/2024, 5:53 AMk: FooKey as FooKey.Bar
eygraber
02/22/2024, 5:54 AMlookup[FooKey.Bar::class]?.invoke(FooKey.Baz)
which I would think would result in a ClassCastExceptiondmitriy.novozhilov
02/22/2024, 5:58 AMeygraber
02/22/2024, 6:13 AMsealed interface FooKey {
data object Bar : FooKey
data object Baz : FooKey
}
and because I wrap the factory with a cast that assumes K
is C
, I could later retrieve a factory for C
, but pass it something that isn't C
as the K
parameter which would cause a ClassCastExceptiondmitriy.novozhilov
02/22/2024, 6:16 AMas
cast may cause ClassCastException
dmitriy.novozhilov
02/22/2024, 6:17 AMC <: K <: FooKey
So you can not pass such C
which won't be subtype of K
eygraber
02/22/2024, 6:18 AMlookup[C::class] = factory
?dmitriy.novozhilov
02/22/2024, 6:24 AMlookup (value): (K) -> Foo<out K> = Function1<K, Foo<out K>>
factory: (C) -> Foo<out K> = Function1<C, Foo<out K>>
Function1
declared as Function1<in T, out R>
factory
may be subtype of lookup
if in
argument of factory
is supertype of the corresponding argument of lookup
, which is not correct (C <: K
, not vice versa)eygraber
02/22/2024, 6:26 AMin
but I guess that makes sense 😅dmitriy.novozhilov
02/22/2024, 6:28 AMlookup
map
You has a relation that type of value depend on the type of specific key, which is possible only in system with dependent types (like in Agda or Arend)
lookup: MutableMap<K' : K, KClass<out K'>, (K' -> Foo<out K')>
dmitriy.novozhilov
02/22/2024, 6:28 AMeygraber
02/22/2024, 6:32 AM