2

スキームはセットカーを持っています!とset-cdr!ですが、set-consはありません!。

のような表現ですか

(設定!c(短所3 c))

エレメント3をリストcに配置します。これは、リストを変更するための適切な/唯一の/最良の/通常の方法ですか?

4

3 に答える 3

5

(set! c (cons 3 c))

さて、この式が何をするのかを明確にしましょう:

  • set!最初の引数として変数を取り、2番目の引数として式を取ります。2番目の引数を評価し、値を変数に割り当てます。
  • cons値とリストを受け取り、指定された値を先頭、指定されたリストを末尾としてリストを作成します。

したがって、ヘッドとテールとしてリストを作成し、そのリストをの値として割り当て(set! c (cons 3 c))ます。この変更は、の同じバインディングにアクセスするコードにのみ表示されます。元のリストを参照する他の変数またはオブジェクトフィールドがある場合でも、それらはその元のリストを参照します。3ccc

これは、一部のコンテキストでは「リストへのアイテムの追加」として大まかに説明できますが、既存のリストを取得して新しいアイテムを持つように変更するのではないため、これは大まかな説明です。むしろ、新しい初期アイテムと元のリストを末尾として使用してリストを作成し、古いリストへの参照の一部(すべてではないかもしれません)を変更して、新しいリストを指すようにします。

「リストへのアイテムの追加」としてカウントされる可能性のある、すぐに考えられる主な2つのことがあります。

  • 既存のリストの構造を変更して、途中または最後のどこかに新しいペアを追加します。用語について本当に厳密な場合、これは「リストにアイテムを追加する」唯一の真のケースです。
  • アイテムをリストの先頭に配置して呼び出し元に返すか、引数として別の関数に渡します(設定なし!)。これはあなたの例よりもさらに緩い言葉ですが、最も一般的なケースでもあります!

最初の例:

(define (insert-at-second-position! item list)
  (set-cdr! list (cons item (cdr list))))

2番目の例:

(define (list-copy xs)
  (if (null? xs)
      '()
      ;; We call list-copy recursively on the tail, and "add an item"
      ;; at the front:
      (cons (car xs)
            (list-copy (cdr xs)))))
于 2012-01-23T19:31:26.323 に答える
1

これがリストを変更する正しい方法ですc。しかし、そのような使用法はまれです。おそらく、あなたがやろうとしていることについてもっと教えていただけますか。

于 2012-01-23T16:35:42.487 に答える
0

型コンストラクター、修飾子、アクセサーについて知っておく必要があります。

ペアは、2つの引数のプロシージャであるconsで構成され、最初の引数(car)はペアの最初の要素であり、2番目の引数(cdr)はペアの2番目の要素です。適切なリストでは、cdrがnullで終了するリストである必要があります。それ以外の場合は、ペアのみです。

ペアセレクター(carとcdr)は、1つの引数であるCONStructedリストを取り、最初の(carを使用)または残りの(cdrを使用)isペア引数を抽出します。

修飾子(セッター)は2つの引数を取ります。既存のCONStruct(ペア、ペアの車、および基本的に構築されたもの)であり、選択された構成を2番目の引数の値に置き換えます。

(set-car! (cons 'a (cons 'b '())) 'c) ;; is the same as
(set! (car (cons 'a (cons 'b '()))) 'c)

とった?

于 2012-01-28T17:37:00.837 に答える