可以使用 cons 来做 ((a . b) . (c . d)) 如果没有任何其他方法或点对不能有这样的第二个元素?
Can one use cons to do ((a . b) . (c . d)) and if not any other means or dot pair cannot have 2nd element like this?
;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z (list x y z00 z01 z10 z11))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;;如果没有任何其他方式或点对不能有这样的第二个元素?
;;; ```
;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z22 (cons '(f g) '(h i)))
(define z2c (cons (cons 'f 'g) (cons 'h 'i)))
(define fgc (cons ('f 'g))); should it be error (nil)
; actually not as 'f is an exoression (quote f) and f for some reason is nil it becomes nil from quote of nil abd so is the second one. now (nil . nil) is (nil)
(define z (list x y z00 z01 z10 z11 z22 z2c fgc))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;; ```
;;;如果没有任何其他方式或点对不能有这样的第二个元素?
;;;可能不会
;;; as the cons join 2 pairs of dotted pairs and can generate one dotted pair
;;; ((a . b) . (c . d)) but the printing rule is reflected the list bias
;;; this new dotted pair will have the first element as (( a . b) ... print as
;;; ((a . b) ...
;;; the 2nd element it will consider whether it is an atom or another dotted pair
;;; (other possibilities like loop back or something else ... not sure)
;;; as (c . d) is a dotted pair the "printing" continues as a list would
;;;
;;; ((a . b) c ...
;;; however the second element of (c . d) is not a dotted pair but an atom and print as
;;; . d) will it becomes
;;; hence even though you form the binary tree head the dot pair would display as a partial list
;;; you can have a list of dotted pairs like z
;;; but not dotted pair of dotted pairs
是的,你可以。该语言有一个很棒的谓词,叫做 equal?
可以让你测试这个:
> (equal? (cons (cons 'a 'b) (cons 'c 'd))
'((a . b) . (c . d)))
#t
> (equal? '((a . b) . (c . d))
'((a . b) c . d))
#t
你甚至可以写一个小的显示函数来证实这一点:
(define (display-thing thing)
(if (cons? thing)
(begin
(display "(")
(display-thing (car thing))
(display " . ")
(display-thing (cdr thing))
(display ")"))
(display thing)))
现在
> (display-thing (cons (cons 'a 'b) (cons 'c 'd)))
((a . b) . (c . d))
> (display-thing '((a . b) . (c . d)))
((a . b) . (c . d))
> (display-thing '((a . b) c . d))
((a . b) . (c . d))
这应该告诉您的是,((a . b) . (c . d))
和 ((a . b) c . d)
只是编写结构相同对象的不同方式。
根据内容不同,视觉效果也不同。如果一对 cdr
包含空列表,它是一个正确的列表,并且不显示点和额外的空列表:
(cons 'a '())
'(a . ())
; ==> (a)
具有 cdr
对的对可以可视化为没有 .
和额外括号的列表元素:
(cons 'b '(a))
'(b . (a))
; ==> (b a)
(cons 'b '(a . c))
'(b . (a . c))
; ==> (b a . c)
这些只是为了让我们可以显示 (1 2 3)
而不是 (1 . (2 . (3 . ())))
,这才是它真正的制作方式。
如果您在 cdr
中没有一对或一个空列表,那么它会退回到显示点对:
(cons 'a 'b)
'(a . b)
; ==> (a . b)
在您的示例中 '((a . b) . (c . d))
因为在点之后有一对(例如 cdr
如果这对,可视化将删除点和一对括号并将其显示为 ((a . b) c . d)
。这是 REPL 显示它的唯一可接受的正确方式,即使您的示例和显示都将作为相同的结构读取。
数字也有类似的问题。在代码中,您可以使用 10
、#xa
和 #o12
来获取数字 10,该值将不知道读取的格式是什么,并且只在 REPL 中显示基数 10 .
;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z (list x y z00 z01 z10 z11))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;;如果没有任何其他方式或点对不能有这样的第二个元素?
;;; ```
;;; <- can one use cons to do ((a . b) . (c . d))?
(define x (cons a b)); nil -- should it be error
(define x (cons 'a 'b)); (a . b)
(define y (cons 'c 'd)); (c . d)
(define z00 (cons x y)) ; (((a . b) c . d) <- cannot use cons to do ((a . b) . (c . d))?
(define z01 (cons x 'y)) ; ((a . b) . y)
(define z10 (cons 'x y)) ; (x c . d)
(define z11 (cons 'x 'y)); (x . y))
(define z22 (cons '(f g) '(h i)))
(define z2c (cons (cons 'f 'g) (cons 'h 'i)))
(define fgc (cons ('f 'g))); should it be error (nil)
; actually not as 'f is an exoression (quote f) and f for some reason is nil it becomes nil from quote of nil abd so is the second one. now (nil . nil) is (nil)
(define z (list x y z00 z01 z10 z11 z22 z2c fgc))
; ((a . b) (c . d) ((a . b) c . d) ((a . b) . y) (x c . d) (x . y))
;;; ```
;;;如果没有任何其他方式或点对不能有这样的第二个元素?
;;;可能不会
;;; as the cons join 2 pairs of dotted pairs and can generate one dotted pair
;;; ((a . b) . (c . d)) but the printing rule is reflected the list bias
;;; this new dotted pair will have the first element as (( a . b) ... print as
;;; ((a . b) ...
;;; the 2nd element it will consider whether it is an atom or another dotted pair
;;; (other possibilities like loop back or something else ... not sure)
;;; as (c . d) is a dotted pair the "printing" continues as a list would
;;;
;;; ((a . b) c ...
;;; however the second element of (c . d) is not a dotted pair but an atom and print as
;;; . d) will it becomes
;;; hence even though you form the binary tree head the dot pair would display as a partial list
;;; you can have a list of dotted pairs like z
;;; but not dotted pair of dotted pairs
是的,你可以。该语言有一个很棒的谓词,叫做 equal?
可以让你测试这个:
> (equal? (cons (cons 'a 'b) (cons 'c 'd))
'((a . b) . (c . d)))
#t
> (equal? '((a . b) . (c . d))
'((a . b) c . d))
#t
你甚至可以写一个小的显示函数来证实这一点:
(define (display-thing thing)
(if (cons? thing)
(begin
(display "(")
(display-thing (car thing))
(display " . ")
(display-thing (cdr thing))
(display ")"))
(display thing)))
现在
> (display-thing (cons (cons 'a 'b) (cons 'c 'd)))
((a . b) . (c . d))
> (display-thing '((a . b) . (c . d)))
((a . b) . (c . d))
> (display-thing '((a . b) c . d))
((a . b) . (c . d))
这应该告诉您的是,((a . b) . (c . d))
和 ((a . b) c . d)
只是编写结构相同对象的不同方式。
根据内容不同,视觉效果也不同。如果一对 cdr
包含空列表,它是一个正确的列表,并且不显示点和额外的空列表:
(cons 'a '())
'(a . ())
; ==> (a)
具有 cdr
对的对可以可视化为没有 .
和额外括号的列表元素:
(cons 'b '(a))
'(b . (a))
; ==> (b a)
(cons 'b '(a . c))
'(b . (a . c))
; ==> (b a . c)
这些只是为了让我们可以显示 (1 2 3)
而不是 (1 . (2 . (3 . ())))
,这才是它真正的制作方式。
如果您在 cdr
中没有一对或一个空列表,那么它会退回到显示点对:
(cons 'a 'b)
'(a . b)
; ==> (a . b)
在您的示例中 '((a . b) . (c . d))
因为在点之后有一对(例如 cdr
如果这对,可视化将删除点和一对括号并将其显示为 ((a . b) c . d)
。这是 REPL 显示它的唯一可接受的正确方式,即使您的示例和显示都将作为相同的结构读取。
数字也有类似的问题。在代码中,您可以使用 10
、#xa
和 #o12
来获取数字 10,该值将不知道读取的格式是什么,并且只在 REPL 中显示基数 10 .