Я изучал рекурсию и TCO. Кажется, что TCO может сделать код многословным, а также повлиять на производительность. например Я ввел код, который принимает 7-значный номер телефона и возвращает все возможные перестановки слов, например, 464-7328 может быть "GMGPDAS ... IMGREAT ... IOIRFCU" Вот код.
/*Generate the alphabet table*/
val alphabet = (for (ch <- 'a' to 'z') yield ch.toString).toList
/*Given the number, return the possible alphabet List of String(Instead of Char for convenience)*/
def getChars(num : Int) : List[String] = {
if (num > 1) return List[String](alphabet((num - 2) * 3), alphabet((num - 2) * 3 + 1), alphabet((num - 2) * 3 + 2))
List[String](num.toString)
}
/*Recursion without TCO*/
def getTelWords(input : List[Int]) : List[String] = {
if (input.length == 1) return getChars(input.head)
getChars(input.head).foldLeft(List[String]()) {
(l, ch) => getTelWords(input.tail).foldLeft(List[String]()) { (ll, x) => ch + x :: ll } ++ l
}
}
Это коротко, и мне не нужно тратить на это слишком много времени. Однако, когда я пытаюсь сделать это в хвостовой рекурсии, чтобы получить TCO'ed. Я должен потратить значительное количество времени, и код становится очень многословным. Я не буду представлять весь код для экономии места. Вот ссылка на ссылку git repo . Наверняка многие из вас могут написать более качественный и лаконичный хвостовой рекурсивный код, чем мой. Я по-прежнему считаю, что в целом TCO является более многословным (например, рекурсия хвостового вызова Фибоначчи и Фибоначчи имеет дополнительный параметр, аккумулятор). Тем не менее, TCO необходим для предотвращения переполнения стека. Я хотел бы знать, как вы подходите к TCO и рекурсии. Реализация схемы Акерманна с TCO в этой теме олицетворяет мою постановку проблемы.