In the end I found a solution based on given advice above. The first thing which should be mentioned is the fact that we shouldn't return nullable Observable at all. If we need to check values passed to combineLatest we should do it before instead of checking it inside combineLatest.
When we remove nullability the method looks like this:
fun <T1, T2, T3, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, merge: (T1, T2, T3) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, Function3 {
value1, value2, value3 ->
merge(value1, value2, value3)
})
}
The only additional thing which I had to change is to replace lambda with Function3 - it solves the problem of type inference.
If you have just two values for combineLatest you can use BiFuntion instead of Function3.
If you need to pas for example 6 variables to combineLatest you can use Function6 etc.
See all the variants below:
fun <T1, T2, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, merge: (T1, T2) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, BiFunction {
value1, value2 ->
merge(value1, value2)
})
}
fun <T1, T2, T3, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, merge: (T1, T2, T3) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, Function3 {
value1, value2, value3 ->
merge(value1, value2, value3)
})
}
fun <T1, T2, T3, T4, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, merge: (T1, T2, T3, T4) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, observable4, Function4 {
value1, value2, value3, value4 ->
merge(value1, value2, value3, value4)
})
}
fun <T1, T2, T3, T4, T5, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, merge: (T1, T2, T3, T4, T5) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, Function5 {
value1, value2, value3, value4, value5 ->
merge(value1, value2, value3, value4, value5)
})
}
fun <T1, T2, T3, T4, T5, T6, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, merge: (T1, T2, T3, T4, T5, T6) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, Function6 {
value1, value2, value3, value4, value5, value6 ->
merge(value1, value2, value3, value4, value5, value6)
})
}
fun <T1, T2, T3, T4, T5, T6, T7, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, observable7: Observable<T7>, merge: (T1, T2, T3, T4, T5, T6, T7) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, observable7, Function7 {
value1, value2, value3, value4, value5, value6, value7 ->
merge(value1, value2, value3, value4, value5, value6, value7)
})
}
fun <T1, T2, T3, T4, T5, T6, T7, T8, R> combineLatest(observable1: Observable<T1>, observable2: Observable<T2>, observable3: Observable<T3>, observable4: Observable<T4>, observable5: Observable<T5>, observable6: Observable<T6>, observable7: Observable<T7>, observable8: Observable<T8>, merge: (T1, T2, T3, T4, T5, T6, T7, T8) -> R): Observable<R> {
return Observable.combineLatest(observable1, observable2, observable3, observable4, observable5, observable6, observable7, observable8, Function8 {
value1, value2, value3, value4, value5, value6, value7, value8 ->
merge(value1, value2, value3, value4, value5, value6, value7, value8)
})
}