У меня есть рекурсивная функция, которую я пытаюсь сделать @tailrec
, имея внутреннюю, рекурсивную часть (countR3
) добавить элементы в очередь (agenda
- scala.collections.mutable.Queue
). Моя идея заключается в том, чтобы затем внешняя часть функции сломалась над повесткой дня и подытожила результаты.Есть ли элегантный способ foldLeft на растущем scala.collections.mutable.Queue?
ПРИМЕЧАНИЕ: Этот был проблемой домашней работы, поэтому я не хочу публиковать весь код; однако, реализация хвостовой рекурсии была не часть домашней работы.
Вот часть кода отношение к моему вопросу:
import scala.collection.mutable.Queue
val agenda: Queue[Tuple2[Int, List[Int]]] = Queue()
@tailrec
def countR3(y: Int, x: List[Int]): Int = {
if (y == 0) 1
else if (x.isEmpty) 0
else if …
else {
agenda.enqueue((y - x.head, x))
countR3(y, x.tail)
}
}
⋮
agenda.enqueue((4, List(1, 2)))
val count = agenda.foldLeft(0) {
(count, pair) => {
val mohr = countR3(pair._1, pair._2)
println("count=" + count + " countR3=" + mohr)
count + mohr
}
}
println(agenda.mkString(" + "))
count
Это почти, кажется, работает ... Проблема заключается в том, что она не перебирать все элементы включены в повестку дня, но он обрабатывает из них. Вы можете увидеть это в приведенном ниже примере: [. Из шести пунктов окончательной повестки дня первые три были обработаны только]
count=0 countR3=0
count=0 countR3=0
count=0 countR3=0
(4,List(1, 2)) + (3,List(1, 2)) + (2,List(2)) + (2,List(1, 2)) + (1,List(2)) + (0,List(2))
Я обычно хорошо осведомлены об опасностях мутирует когда вы повторяете его, скажем, Java. Но очередь - это своего рода лошадь другого цвета. Конечно, я понимаю, что я мог бы просто написать императивный цикл, например, так:
var count = 0
while (!agenda.isEmpty) {
val pair = agenda.dequeue()
count += countR3(pair._1, pair._2)
}
Это работает отлично, но это время Scala, я исследую, чтобы увидеть, если есть более функционально элегантный путь.
Любые предложения?
Не совсем идиоматично, я бы согласился, но похоже, что это соответствовало бы чисто функциональности. Хороший ответ! И интересно, «повестка дня».foldLeft' обрабатывал больше, чем только первоначально выставленные предметы; казалось, что он просто не работал над копией начальной очереди. Возможно, это остановилось, когда «последний» элемент привел к добавлению большего количества элементов в очередь или что-то в этом роде. –