I'm trying to do something here with generics and ...
# announcements
j
I'm trying to do something here with generics and can't quite get it to work without an unsafe cast. Basically, I'm using jOOQ (http://jooq.org), and want to create a condition in similar ways on different Field<T>s in different places in the code. So the Field in question and the value I want to compare it against change, but the joining of those field/values is relatively the same. here's what I have so far, which works, but I have to cast my Field<*> to a Field<Any> in order to actually use its
eq()
method -- i need the same cast if i change it to <out Any>, and if i change it to <in Any> the
createCondition()
function works but I can't invoke it in `main()`:
Copy code
data class ConditionData<T>(
    val field: Field<T>,
    val value: String,
    val transform: (String) -> T
)

fun createCondition(vararg things: ConditionData<*>): Condition {
    return things
        .map {
            val value = it.transform.invoke(it.value)
            (it.field as Field<Any>).eq(value)
        }
        .reduce { a, b -> a.and(b) }
}

fun main() {
    print(
        createCondition(
            ConditionData(DSL.sum(Tables.DATA.WATCH_TIME), "1234567.234") { s -> BigDecimal(s) },
            ConditionData(Tables.DATA.MONTH, "2018-07-01") { s -> LocalDate.parse(s) },
            ConditionData(Tables.DATA.CHANNEL, "HBO") { s -> s }
        )
    )
}
output of the main is correct:
Copy code
(
  sum("data"."watch_time") < 1234567.234
  and "data"."month" < date '2018-07-01'
  and "data"."channel" < 'HBO'
)
g
Would be nice to make the example more focused on the exact problem: https://en.wikipedia.org/wiki/Minimal_working_example Also, not sure but don't you compare
Field<T>
with
T
here?
Copy code
val value = it.transform.invoke(it.value)
 (it.field as Field<Any>).eq(value)
j
yeah sorry, this is the short version compared to my actual code. i can try to simplify it more. i think the main issue is that for each CondiitionData instance, <T> is constant, but it can vary between each element of the vararg param?