2013-05-04 34 views
5
(define .. 
    (lambda (start stop) 
    (cond ((> (add1 start) stop) (quote())) 
      ((eq? (add1 start) stop) (sub1 stop)) 
      (else (cons start (.. (add1 start) stop)))))) 

Tôi đã xác định một hàm phạm vi đơn giản. Mục đích là choPhạm vi đệ quy trong Lisp thêm một khoảng thời gian?

(.. 1 5) --> (1 2 3 4) 

Thay vào đó, một thời gian kỳ lạ đã được thêm vào tuple của tôi và tôi không có ý tưởng tại sao:

(.. 1 5) --> (1 2 3 . 4) 

Tôi không hiểu tại sao điều này đang xảy ra. Any help is appreciated

+0

Trường hợp nào trong 'cond' được sử dụng khi bạn làm' (.. 1 2) '? Nó quay trở lại cái gì? – Barmar

Trả lời

15

Một danh sách trong Đề án là một trong hai danh sách trống () (còn gọi là nil trong một số Lisps), hoặc một tế bào khuyết điểm mà car (còn gọi là first) là một phần tử của danh sách và có cdr (còn được gọi là rest) là phần còn lại của danh sách (ví dụ: danh sách khác) hoặc một nguyên tử kết thúc danh sách. Người kết thúc thông thường là danh sách trống (); danh sách chấm dứt bởi () được cho là "danh sách thích hợp". Danh sách chấm dứt bởi bất kỳ nguyên tử nào khác được gọi là "danh sách không đúng". Danh sách (1 2 3 4 5) chứa các phần tử 1, 2, 3, 4 và 5 và được chấm dứt bằng (). Bạn có thể xây dựng nó bằng cách

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5()))))) 

Bây giờ, khi hệ thống in một tế bào khuyết điểm, trường hợp tổng quát là in nó bằng cách

(car . cdr) 

Ví dụ, kết quả của (cons 1 2) được in như

(1 . 2) 

Vì danh sách được tạo từ ô khuyết điểm, bạn cũng có thể sử dụng ký hiệu này cho danh sách:

'(1 2 3 4 5) == 
'(1 . (2 . (3 . (4 . (5 .()))))) 

Đó là khá phiền phức, mặc dù, vì vậy hầu hết lisps (tất cả những gì tôi biết) có một trường hợp đặc biệt để in tế bào nhược điểm: nếu cdr là danh sách (hoặc một nhược điểm di động, hoặc ()), sau đó don' t in các ., và không in dấu ngoặc đơn xung quanh của cdr (mà nó nếu không sẽ có, vì nó là một danh sách). Vì vậy, nếu bạn thấy kết quả như

(1 2 3 . 4) 

điều đó có nghĩa là bạn đã có một danh sách không đúng được kết thúc bởi nguyên tử 4. Cấu trúc có cấu trúc

(1 . (2 . (3 . 4))) 

Bây giờ câu hỏi đặt ra là: trong mã của bạn đã xây dựng danh sách bị hỏng?.. luôn phải trả về một danh sách thích hợp, vì vậy chúng ta hãy nhìn vào các trường hợp: Trường hợp đầu tiên luôn luôn trả về một danh sách thích hợp (danh sách trống):

((> (add1 start) stop) (quote())) 

Trường hợp thứ hai có vẻ như nó có thể trở lại một cái gì đó không phải là một danh sách (giả định rằng (sub1 stop) == (- stop 1)):

((eq? (add1 start) stop) (sub1 stop)) 

Bây giờ, nếu .. được hoạt động một cách chính xác, sau đó trường hợp thứ ba sẽ luôn trả về một danh sách thích hợp (từ (cons x y) là danh sách thích hợp nếu y là):

(else (cons start (.. (add1 start) stop))) 

Làm cho trường hợp thứ hai của bạn trả về một danh sách và bạn sẽ hoàn tất.

+0

Cảm ơn lời khuyên của bạn - giải thích rõ ràng và dễ hiểu. – vim

1

biểu hiện của bạn (sub1 stop) cần đọc (list (sub1 stop))

Để cons để xây dựng một danh sách phù hợp, yếu tố thứ hai cần phải được một danh sách riêng của mình. Do đó, chức năng của bạn .. phải trả về danh sách một số loại cho mọi mệnh đề cond.

1

Remove này là một phần của cond

((eq? (add1 start) stop) (sub1 stop)) 

Nó gây ra một kết thúc sớm.

+0

+1. càng đơn giản càng đẹp !!! :) :) –

Các vấn đề liên quan