Проверьте, является ли аргумент списком или атомом

Как проверить, является ли что-то атомом? Я ищу что-то вроде number? или list?.

Ответы

Ответ 1

Обычно вы также хотите исключить пустой список:

(define (atom? x) (not (or (pair? x) (null? x))))

или, если вы хотите быть более педантичным, тогда также запретите векторы:

(define (atom? x) (not (or (pair? x) (null? x) (vector? x))))

И, конечно, вы можете добавить гораздо больше здесь - поскольку он помечен как вопрос с ракеткой, вы можете захотеть добавить хеш-таблицы, структуры и т.д. Таким образом, проще также указать типы значений, которые вы считаете атомы:

(define (atom? x)
   (ormap (lambda (p) (p x)) (list number? symbol? boolean? string?)))

или используя систему контрактов ракетки:

(define atom? (or/c number? symbol? boolean? string?))

Ответ 2

Когда различные схемы не включают его, я часто видел atom?, определяемый следующим образом:

(define (atom? x) (not (pair? x)))

Это вернет true, если x не является парой (или списком). Он вернет true для чисел, строк, символов и символов, в то время как symbol? вернет true для символов, естественно. Это может быть или не быть тем, что вы хотите. Сравните пример Ясира Арсанукаева:

1 ]=> (map atom? (list 42 'a-symbol (list 12 13) 'foo "yiye!"))

;Value 13: (#t #t #f #t #t)

Он использует pair?, потому что он проверяет правильные списки, такие как (1 2 3), пары, такие как (a . b), а list? возвращает false для точечных пар и списков с точками.