Is it possible to do something like this? I want t...
# announcements
n
Is it possible to do something like this? I want to avoid switching on each potential type. Does type erasure make it impossible?
Copy code
data class DataDriver<T>(val valueCalculator: (T) -> Int)

val dataDriver = listOf(
        DataDriver<T1>( ::calcValue1),
        DataDriver<T2>( ::calcValue2)
)

// Using reified worked here
private inline fun <reified T> query(isSubmitted: Boolean): List<T> { 
	return realm.where<T>().equalTo("submitted", isSubmitted).find()
}

fun calcValue1(item: T1) -> Int {
	return 42
}

// But what about here?
// Apply transforms to get a list of calculated items,
// calling the proper query and calculator based on the type.
// Without resorting to type checks for each type.
// IS THIS POSSIBLE?
dataDriver.map {
	query()  // type inference fails here
		.map(::valueCalculator) 
}
k
I don't think there's a way to iterate over a list of reified types like this, you'll have to go for either reflection of manual type checking.
n
@karelpeeters Which is kind of slow, right?
k
Reflection? Things like
where
must use reflection behind the scenes anyway to do something with the reified type, so it's not going to be slower.
(at least that's my guess, I don't know what
where
is from)
d
What you want is not possible. The type of the elements is not retained here and it is not possible to do so without serious refactoring. A list only contains one type, not multiple.
r
Yeah you can write
reified
everywhere you want
List
will never retain any type
n
@ribesg Actually, my issue is here.
Copy code
dataDriver.map {
    query()  // type inference fails here
        .map(::valueCalculator) 
}
Could I solve this by restricting the type in
query()
?
d
You could, but again, it would then only be one type for all elements in the list.
n
It would be the base class. So, run-time dispatching to the proper subclass would not work? Is this what you mean?
r
The type used in
query
would be the type of the list, it’s simple
d
Correct. For that you would need a variant of
query
that can accept e.g. a
KClass
instead of a reified type parameter.
n
@diesieben07 But then, I would have to switch on this type. Things like
map
would not work…
d
I am not sure what you mean by that.
n
I mean, it is not possible to write something like this:
Copy code
dataDriver.map {
    query()  // type inference fails here
        .map(::valueCalculator) 
}
query()
is a generic function here.
r
You could use various calls to
.filterIsInstance<X>()
d
Yes, it is.
dataDriver.map { query(it::class) }
👍 1
But then you need to change
query
to accept
KClass
instead of a reified type parameter
n
@diesieben07 Thanks, I will give it a try! I do not like reified types anyway. They feel like an ugly workaround that leads to code bloat .