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.Bareygraber
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 ClassCastExceptiondmitriy.novozhilov
02/22/2024, 6:17 AMC <: K <: FooKey
So you can not pass such C which won't be subtype of Keygraber
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