As was stated earlier, Kotlin provides extension functions. These can be an enormously helpful alternative to using just compose() and lift().
For instance, we could not use transformers and compose() to turn an Observable<T> into a Single<R>. But this is more than doable with Kotlin extension functions. In the following code (the ch12_09.kt example), we create a toSet() operator and add it to Observable<T>:
import io.reactivex.rxjava3.core.Observable
fun main(args: Array<String>) {
val source =
Observable.just("Alpha", "Beta", "Gama", "Delta", "Epsilon")
val asSet = source.toSet()
println(asSet.blockingGet())
}
fun <T> Observable<T>.toSet() =
collect({ HashSet<T>() }, { set, next -> set.add(next) })
.map { it as Set<T>...