2017-02-19 9 views
-1

私は、ユーザーからリストを取得し、このリストを1つの簡略化リストにまとめた関数を作成しています。この関数はリストの最初の項目だけを返すように見えますが、残りの部分は返しません。なぜこれをやっているの?なぜ私のLisp関数は私にこの出力を与えていますか?

例:

> (flatten '(a() b (c d)) 
(a b c d) 

これは私がこれまで

(defun flatten (list) 
(cond 
    ((null list)t) 
     (list (first list) (rest list)) 
     (t(append (flatten (first list)) 
       (flatten (rest list))) 
    (t(cons (first list (flatten (rest list)))))))) 

それは、あなたが更新されたコードを元の質問を編集している

> (flatten '(a() b (c d))) 
(NIL B (C D)) 
+1

'(リスト(最初のリスト))' - 最初の要素だけを返すように指示しているからですか? – melpomene

+0

@melpomene私はちょうど私が行ったことを理解しました。明確化のためにありがとう –

+4

あなたのコードはこう言っています: '(ヌルリスト)'(すなわち、 'list'が空/ nilならば)' t'を返します。それ以外の場合、 'list'(つまり、listが空でない/無しでない場合)、最初の要素を取得して無視し、残りの部分(最初の要素を除くすべて)を取得して返します。最初の2つの条件の1つが常に真であるため、残りのコードは無関係です。 – melpomene

答えて

3

を与えている出力が持っているものですそれを動かすターゲットにします。私はMqを(lispのモード)でそれをインデントするためにEmacsを依頼した後、現在、あなたのコードは、以下のいずれかになります。

(defun flatten (list) 
    (cond 
    ((null list)t) 
    (list (first list) (rest list)) 
    (t (append (flatten (first list)) 
       (flatten (rest list))) 
     (t (cons (first list (flatten (rest list)))))))) 
;; ^^^ Something is not good, why is the clause indented? 

括弧構造インデントは、この構造を印刷する方法であるのに対し、コンピュータ用のコード、人間の読者のために。この冗長性により、一方が他方に一致しない場合にソースコードの問題を検出することができます。ここでは、(t cons)はcond句ではなく、前の句の中にネストされています。

第2に、コメントに記載されているように、condはテストが成功する最初の句に移動します。 (cond (t X) ...)を書き込んだ場合、...の部分には何もコードの意味が変更されず、常にXが返されます。 nilからeqあるlist

  1. (null list)テスト:次のようにあなたのコードでは、テストします。
  2. listlistがリストであるかどうかをテストします。それを検出する述語はlistpです。 listだけをこのように置くと、listが一般化された真の値であるかどうかを尋ねることになります。これは前にnil(前の節)を除外したときに必ず真です。
  3. 既定の句(t ...)には、以前のテストが失敗しないため、使用する方法がありません。ここで

スケルトンです:

(defun flatten (form) 
    (cond 
    ((null list) ...) 
    ((consp list) ...) 
    (t ...))) 

代わりのconspあなたがlistpを書きますが、定義により、リストがnilや短所セルのいずれかであることに注意してください、そうconspはもう少し明示的であるといことができnilのテストと重複しません。また、私はいつも見つかっているパターンであるフォームのタイプに対して常にテストすることに注意してください。そのため、typecaseを使用することをお勧めします。

+1

スケルトンで遊んでいただきありがとうございます私はそれを理解することができました –

関連する問題