Пунктирные списки в схеме Guile - PullRequest
0 голосов
/ 23 января 2020

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

Это то, что я не ожидал и не может понять:

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

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

Ответы [ 2 ]

3 голосов
/ 23 января 2020

Обратите внимание, что (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)))
2 голосов
/ 23 января 2020

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

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

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

...