jozefg's answer прав, указывая на то, что (cons? x)
не то же самое, как (not (empty? x))
, в целом, потому что есть вещи (например, номера), которые не являются ни минусы клетки, ни пустой список.
Однако ваша переменная была list-name
, поэтому у вас может быть некоторая причина ожидать, что ее значение, по сути, является списком. Список на Схеме:
- пустой список; или
- a cons cell, чей
car
является элементом списка first
, а cdr
является rest
списка.
Из-за этого, если вы пишете функцию, которая требует списка будет принято в, то делает имеет смысл, чтобы просто проверить для тривиального случая (пустой список) с empty?
, и принять на себя , поскольку вам нужен список, что все, что не соответствует этому случаю, является ячейкой cons, на которую вы можете позвонить cdr
и cdr
. Это происходит потому, что в то время как
(cons? x) == (not (empty? x))
не соответствует действительности значений в общем, является верно для списков. То есть, если вы уже знаете, что lst
список, затем
(cons? lst) == (not (empty? lst))
является истинным. Есть ряд функций, которые делают то же самое, когда мы говорим о списках и ячейках cons. Например, empty?
и null?
делают то же самое, но они сигнализируют немного другое намерение со стороны программиста.Точно так же, car
и cdr
сделать то же самое, как и first
rest
, но car
и cdr
сигнал, который вы могли бы что-то для обработки в виде пары из двух вещей, в то время как first
и rest
четко сигнализировать намерение, что вы работаете со списком.
Ваш код, поскольку он, кажется, ожидает список, должен, вероятно, быть следующим, поскольку для списка, если это не пустой список, он должен быть минусом.
(define (f lst)
(cond
[(empty? lst) empty]
[else "do something]))
В целом, код, который вы пишете, должен зависеть от того, какой тип ввода вы ожидаете. Например, в первом случае нормально проверять наличие пустого и принимать минусы иначе, потому что вы ожидаете список. Во втором случае вы должны проверить все виды вещей, которые вы можете увидеть.
(define (frob-list lst)
(cond
[(empty? lst) empty] ; arg is()
[else ...])) ; arg is (x . y)
(define (frob-object obj)
(cond
[(null? obj) ...] ; arg is()
[(cons? obj) ...] ; arg is (x . y)
[(number? obj) ...] ; arg is r
... ; arg is ...
[else ...])) ; else ...
Это правильно. _However_, если аргумент, входящий, как известно, является списком (будь то с помощью предыдущих проверок или потому, что это то, что требуется функции), тогда он имеет смысл иметь простой if/else. 'empty? 'проверяет, есть ли у вас тривиальный случай списка, а _everything else_ должен быть списком, на котором вы можете использовать' first' и 'rest'. –