https://kotlinlang.org logo
k

kirillrakhman

07/28/2016, 11:40 AM
@jkbbwr: I implemented your send to generator idea with coroutines:
Copy code
fun <T : Any, R : Any> generate(coroutine c: GeneratorController<T, R>.() -> Continuation<Unit>): (T) -> R {
    val controller = GeneratorController<T, R>()
    controller.c().resume(Unit)
    return controller
}

class GeneratorController<T, R> : (T) -> R {

    private lateinit var nextStep: Continuation<T>
    private var nextOutput: R? = null

    suspend fun yieldGet(output: R, c: Continuation<T>) {
        nextOutput = output
        nextStep = c
    }

    override fun invoke(input: T): R {
        nextStep.resume(input)
        return nextOutput as R
    }

}

fun main(args: Array<String>) {
    val generator = generate<Int, String> {
        var i = 1
        var output = ""

        while (true) {
            val input = yieldGet(output)
            output = (input * i).toString()
            i *= 2
        }
    }

    println(generator(1))
    println(generator(1))
    println(generator(1))
}
prints
Copy code
1
2
8