我正在尝试编写一个简单的Scheme函数,它将给定列表转换为它的点对符号。
例如,如果输入是 -
((1 (2)) 3 ((4)))
对应于它的虚线对符号以及应该在函数中保留哪些规则来编写这样的逻辑。
任何这样的指示都会非常感激。
答案 0 :(得分:1)
这是长形式:
((1 . ((2 . ()) . ())) . (3 . (((4 . ()) . ()) . ())))
编写一个函数来打印长格式很简单:
"("
或#\(
car
" . "
cdr
")"
或#\)
答案 1 :(得分:1)
car
和cdr
实际上是对您的过程的递归调用:
(define (display-dotted sexp)
(cond
((null? sexp) (display "()"))
((pair? sexp) (display "(")
(display-dotted (car sexp))
(display " . ")
(display-dotted (cdr sexp))
(display ")"))
(else (display sexp))))
然后
> (display-dotted '((1 (2)) 3 ((4))))
((1 . ((2 . ()) . ())) . (3 . (((4 . ()) . ()) . ())))
答案 2 :(得分:0)
如果您实现自己的LISP并且需要记住,那么请记住,实际上比将列表显示为列表而不是点对符号更简单。这是一种方法:
(define (my-display x)
(let recur ((x x) (list-mode #f))
(cond ((pair? x)
(display (if list-mode " " "("))
(recur (car x) #f)
(recur (cdr x) #t))
((not list-mode) (display x))
((null? x) (display ")"))
(else
(display " . ")
(display x)
(display ")")))))
你知道我们需要保持状态告诉我们我们正在处理一个列表,因为它看起来取决于cdr
。你想要的是即使cdr
是()
或pair?
,所有对都是一样的,所以它更简单:
(define (my-display x)
(let recur ((x x))
(cond ((pair? x)
(display "(")
(recur (car x))
(display " . ")
(recur (cdr x))
(display ")"))
(else (display x)))))
当然,真正的实现可能有更多的逻辑来显示不同的原子值,因为这些实际上只是解决了这些对。制作自己的Lisp Zozotez时,打印是读后的第二大功能。