2017-11-06 11 views
0

Schemeに、xという要素の位置を既存のリストの位置に追加するプロシージャを実装しようとしています。これは私が思いついたものです:リストに要素を追加する

(define empty-list '()) 
(define (add i x L) 
    (cond ((null? L) (set! L (list x))) 
     ((= i 0)(set! L (cons x L))) 
     (else (set! L (cons (car L) 
          (add (- i 1) x (cdr L)))) 
    ))) 

(add 0 1 empty-list) -> returns() 
(add 1 2 empty-list) -> returns() 
(add 2 3 empty-list) -> returns() 

コードは既存のリストを更新しません。しかし、私がちょうど実行した場合 (set! empty-list (list 1))または (set! empty-list (cons 2 empty-list))うまく動作します。 私は間違っていることを理解するのに苦労しています。

+0

パラメータに値を割り当てることは、慣れ親しんでいる他の言語とまったく同じように機能します。つまり、関数の外では効果がありません。入力を変更する意図があることは絶対に確信していますか? Schemeプログラムで行うことは非常にまれです。 – molbdnilo

答えて

0

set!を使用している場合、実際の値は変更されませんが、最も特定のバインディングに新しい値が割り当てられます。 JavaScriptでは、同じように動作します。

function add (arr, element) { 
    arr = arr.concatenate([element]); 
    return arr; 
} 

const test = [1, 2, 3]; 
add(test, 4); // => [1, 2, 3, 4] 
test;   // => [1, 2, 3] 

これらのスキームのプロシージャは、通常、変更されていません。スキームで

(define (add i x L) 
    (cond 
    ((null? L) (list x)) ; might not be at correct position 
    ((= i 0) (cons x L)) 
    (else (cons (car L) (add (- i 1) x (cdr L)))))) 

(add 1 'b '(a c)) ; ==> (a b c) 
0

多くの関数型言語のように、我々は、更新された引数での定期的な機能を呼び出すことにより、状態を更新します。あなたが値をset!を削除した場合には、正しい値を返します。

(define (add i x l) 
    ;; handle base cases outside of recursion, such as 
    ;; if the starting list is empty, `i` is disregarded etc. 
    (cond [(null? l) (cons x l)] 
     [(null? (cdr l)) 
     (if (<= i 0) 
      (cons x l) 
      (append l (list x)))] 
     [else 
     (let recur ([start l] [index 0]) 
      ;; base case 
      (if (= index i) 
       (cons x start) 
       ;; this is how states are updated 
       (cons (car start) (recur (cdr start) (+ index 1)))))])) 


;; > (add 3 'newguy '(mary peter nguyen joo kim)) 
;; '(mary peter nguyen newguy joo kim) 
関連する問題