You need to make the function suspend and an extension on SequenceScope, because SequenceScope is defined as @RestrictsSuspension, which means that it uses suspend in a special way, and hence it isnât a special suspend function. IMO the code even looks cleaner this way:
suspend fun SequenceScope<TreeNode>.drillDown(
base: TreeNode,
pruner: (node: TreeNode) -> Boolean
) {
base.children.forEach { child ->
if (pruner(child)) {
yield(child)
drillDown(child, pruner)
}
}
}
data class TreeNode(
val children: List<TreeNode>
)
The calling function needs a little tweak as well.
val seq0 = sequence {
drillDown(root, pruner)
}
I am not sure what you mean by âa special suspend functionâ.
It seems like if it uses âsuspendâ in a special way it should be a special suspend function.
In any case, thanks.
functions that have a receiver annotated with @RestrictsSuspension are not allowed to call arbitrary suspend methods, hence theyâre âspecialâ in that it forces you to call only other functions that take the same type as a receiver, such as yield. What that ultimately means is that sequence does some special behind-the-scenes work with the coroutines machinery. In this case, sequences donât produce new values until a value is required, so the function passed to the sequence is suspended until required.