I am learning Kotlin and for the love of it, I cannot get the yield/sequence straight. Could someone please correct my code?
fun Sequence<Int>.mapIterable(transform: (Int)->Int) = sequence {
this.forEach({ x -> yield(transform(x)) })
}
fun Sequence<Int>.product(): Int {
return this.reduce({ acc,x -> acc*x })
}
infix fun Int.powerof(exponent: Int): Int {
return (1..exponent).mapIterable({ x -> this }).product()
}
fun main() {
println(2 powerof 10)
}
mapIterabledoesn't compile becausethisis referring to the receiver of thesequence { ... }lambda, which is aSequenceScope<Int>. ThisSequenceScopeis what allows you to callyield. What you meant is the receiver ofmapIterable, which you can write asthis@mapIterable.Note that
mapIterableis just reinventingSequence.map. Just usemapinstead.productis fine, but usingreducemeans that this throws an exception when the sequence is empty. I would write this withfold:In
powerOf,(1..exponent)is not aSequence<Int>, but anIntRange. You can convert it to aSequence<Int>usingasSequence:An alternative way is
generateSequenceto generate an infinite sequence ofthis, and thentake(exponent).That said, doing things lazily here isn't really much better than just creating a
IntArray(exponent) { this }. The highest exponent you can meaningfully compute with this method is 31 (2^31 and you already reached the max value ofInt). 31 integers in an array isn't that much.