Можно ли реализовать в Scala что-то эквивалентное оператору Python yield
, где он запоминает локальное состояние функции, где оно используется, и "дает" следующее значение при каждом его вызове?
Я хотел иметь что-то вроде этого, чтобы преобразовать рекурсивную функцию в итератор. Пример:
# this is python
def foo(i):
yield i
if i > 0:
for j in foo(i - 1):
yield j
for i in foo(5):
print i
Кроме того, foo
может быть более сложным и повторяется через некоторый ациклический граф объекта.
Дополнительное редактирование: Позвольте мне добавить более сложный пример (но все же простой): Я могу написать простую рекурсивную функцию печати, когда она идет:
// this is Scala
def printClass(clazz:Class[_], indent:String=""): Unit = {
clazz match {
case null =>
case _ =>
println(indent + clazz)
printClass(clazz.getSuperclass, indent + " ")
for (c <- clazz.getInterfaces) {
printClass(c, indent + " ")
}
}
}
В идеале я хотел бы иметь библиотеку, которая позволяет мне легко изменять несколько утверждений и работать как Iterator:
// this is not Scala
def yieldClass(clazz:Class[_]): Iterator[Class[_]] = {
clazz match {
case null =>
case _ =>
sudoYield clazz
for (c <- yieldClass(clazz.getSuperclass)) sudoYield c
for (c <- clazz.getInterfaces; d <- yieldClasss(c)) sudoYield d
}
}
Кажется, продолжения позволяют это сделать, но я просто не понимаю концепцию shift/reset
. Будет ли продолжение в конечном итоге превращаться в основной компилятор и можно ли извлечь сложность в библиотеке?
Изменить 2: Богатый ответ в этом другом потоке.