2017-11-06 14 views
0

스키마에서 x 요소를 기존 목록에 i 위치에 추가하는 절차를 구현하려고합니다. 이것은 내가 생각해 낸 것입니다 :목록에 요소 추가

(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!을 사용하는 경우 실제 값은 변경하지 않지만 가장 구체적인 바인딩에는 새 값을 할당합니다. 자바 스크립트에서도 동일하게 작동합니다 :

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)