Пунктирные списки в Guile Scheme

Как я могу специально проверить точечные списки в форме (a . b) Guile? dotted-list из srfi-1 странным образом возвращает #t также, например, для Числа (с каких это пор числа тоже являются списками? .gnu.org/software/guile/manual/html_node/SRFI_002d1-Predicates.html)! И pair? будет оцениваться как #t также для обычных списков. Есть ли способ отличить конструкцию (a . b) от других вещей, тогда как часть b (cdr) сама по себе может быть любым объектом, включая другие списки ассоциаций и т. д.?

Вот чего я не ожидал и не могу понять:

(dotted-list? '(c . ((d . 3)
                     (e . 4)))) ; ===> #f

(dotted-list? 3) ; ===> #t

person Student    schedule 23.01.2020    source источник
comment
Пара, у которой cdr является правильным списком, является правильным списком. Пунктирная версия будет выглядеть так: «(c. ((d. ​​3) . (e. 4))).   -  person molbdnilo    schedule 23.01.2020


Ответы (2)


Обратите внимание, что (atom . (x1 ... xn)) — это еще один способ записи (atom x1 ... xn), поэтому (c . ((d . 3) (e . 4))) просто эквивалентен (c (d . 3) (e . 4)), который представляет собой не что иное, как список из трех элементов (и по этой причине dotted-list? в этом случае возвращает false).

Если вам не нравится определение dotted-list?, данное в srf-1, тогда определите свою собственную версию:

(define (my-dotted-list? l)
  (and (dotted-list? l)
       (pair? l)))
person Renzo    schedule 23.01.2020

Если вам нужно отдельное определение (которое не зависит от существующего определения, с которым вы не согласны), то я думаю, что это разумно:

(define (dotted-list? c)
  (and (cons? c)
       (cond [(cons? (cdr c))
              (dotted-list? (cdr c))]
             [(null? (cdr c))
              #f]
             [else #t])))

Обратите внимание, что, как и любое простодушное определение, оно не останавливается на круговых списках.

person Community    schedule 23.01.2020