Чтобы упростить жизнь, вы должны смоделировать данные. Поскольку типов нет, мы можем сделать это неформально.
Какова структура ввода?
Мы можем смоделировать его как «Определения данных» из Как разрабатывать программы . Прочтите раздел «Переплетенные данные», потому что наше определение данных похоже на определение S-выражения .
; A NestedElem is one of:
; - Atom
; - NestedList
; An Atom is one of:
; - Number
; - Symbol
; A NestedList is one of
; - '()
; - (cons NestedElem NestedList)
Мы можем определить предикат atom?
, чтобы помочь нам различать предложения видов данных в нашей программе.
; Any -> Boolean
; is `a` an atom?
(define atom?
(lambda (a)
(or (number? a)
(symbol? a))))
Структура программы должна соответствовать структуре данных.
Таким образом, мы определяем «шаблон» по нашим данным. Он различает и разлагает каждую информацию на пункты. Это далее деструктурирует права пункта.
; NestedElem -> ...
(define nested-elem-template
(lambda (ne)
(cond
[(atom? ne) ...]
[else ...])))
; Atom -> ...
(define atom-template
(lambda (atom)
(cond [(number? atom) ...]
[(symbol? atom) ...])))
; NestedList -> ...
(define nested-list-template
(lambda (nl)
(cond [(null? nl) ...]
[else (... (car nl)... (cdr nl))])))
Мы определенно знаем больше о данных. (car nl)
в nested-list-template
имеет тип NestedElem. Поэтому мы можем заполнить некоторые ...
вызовами шаблонов, которые имеют дело с такими данными. В том же духе мы можем обернуть рекурсивные вызовы в выражения известных нам типов данных.
; NestedElem -> ...
(define nested-elem-template
(lambda (ne)
(cond
[(atom? ne) (atom-template ne)]
[else (nested-list-template ne)])))
; Atom -> ...
(define atom-template
(lambda (atom)
(cond [(number? atom) ...]
[(symbol? atom) ...])))
; NestedList -> ...
(define nested-list-template
(lambda (nl)
(cond [(null? nl) ...]
[else (... (nested-elem-template (car nl))
... (nested-list-template (cdr nl)))])))
Теперь мы можем «заполнить пробелы».
Мы можем «фильтровать», «отображать» и «сворачивать» эту структуру данных. Все они могут быть определены с использованием шаблона в качестве основы.
Примечание 1 : Ваш HW просит вас выполнить несколько задач:
- удалить символы
- суммировать числа
cons
сумма в каждом списке
Не пытайтесь делать все в одной функции. Делегируйте в несколько вспомогательных функций / обходов.
Примечание 2 : Я не моделировал тип вывода. Это то же самое, что и тип ввода, за исключением того, что Symbol больше не является атомом.