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

私は単純範囲機能を定義しました。 意図が代わりにLispの再帰的な範囲にピリオドが追加されますか?

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

ために、奇妙な期間は私のタプルに追加されていると私は理由は考えていません:なぜこれが起こっている私は理解していない

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

を。任意の助けを、スキーム中のリスト(また、いくつかのLispでnilとして知られている)空のリスト()のいずれかである、又はそのcar(またfirstとしても知られる)コンスセルがリストの要素であり、そのcdr

+0

あなたは '(.. 1 2)'を実行するときに 'cond'の中のどのケースが使われますか?それは何を返すのですか? – Barmar

答えて

15

を理解されたいですrestとも呼ばれる)は、リストの残りの部分(つまり、別のリスト)か、リストを終了するアトムのいずれかです。従来のターミネータは空のリスト()です。 ()で終わるリストは「適切なリスト」と呼ばれます。他の原子によって終了されたリストは、「不適切なリスト」と呼ばれます。リスト(1 2 3 4 5)には、要素1,2,3,4、および5が含まれ、終了は()です。システムプリントコンス・セルは、一般的なケースは、例えば

(car . cdr) 

によってそれを印刷するときに、今

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

ことによってそれを構築することができ、(cons 1 2)の結果は

として印刷されます
(1 . 2) 

リストはコンスセルで構築されているので、あなたもリストにこの表記を使用することができます。

ほとんどのLisp(私の知っていることすべてが)コンスセルを印刷するための特殊なケースを持っているので、しかし、むしろ不格好だ
'(1 2 3 4 5) == 
'(1 . (2 . (3 . (4 . (5 .()))))) 

cdrリスト(別のコンス・セル、または()のいずれか)である場合には、「ドン.を印刷し、cdrの囲み括弧を印刷しないでください(リストであるため)。あなたは

(1 2 3 . 4) 

のような結果を見ているのであれば、それはあなたが原子4で終了し、不適切なリストを持っていることを意味します。それは構造を持っています

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

ここであなたのコードではリストの作成は失敗しましたか?..は、常に適切なリストを返すことになって、それでは例を見てみましょうされています。最初の場合は、必ず適切なリスト(空のリスト)を返します:

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

それはない何かを返すことができるように第二ケースが見えますリスト((sub1 stop) == (- stop 1)があると仮定):..が正常に機能している場合

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

さて、第3の場合は、常に(yがある場合(cons x y)が適切なリストであるため)適切なリストを返すことになります。

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

2番目のケースがリストを返すようにしてください。すべての設定が必要です。

+0

アドバイスをいただきありがとうございます - 説明ははっきり分かりやすく分かりました。 – vim

1

consが適切なリストを構築するためには(list (sub1 stop))

を読み取る必要がある(sub1 stop)あなたの表現、2番目の要素はリスト自体にする必要があります。したがって、関数..は、すべてのcond句に対して何らかの型のリストを返さなければなりません。

1

それは時期尚早仕上げを引き起こしている

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

指揮のこの部分を削除してください。

+0

+1。少ないほうがいいですね !!! :) :) –