2016-03-09 4 views
0

Ниже приведен пример кода, загруженного для проблемы: Счетчик увеличивается на единицу, изменяя его для передачи в качестве аргумента значения, используемого для приращения. Е.Г.,У меня есть некоторые трудности в понимании Исходный код схемы

(let ((c (create-counter))) (+ (c) (c) (c) (c))) => 6 
(let ((c (create-counter 2))) (+ (c) (c) (c) (c))) => 12 

Исходный код:

(define create-counter 
(lambda ([num '()]) 
    (let ((temp (lambda (incr) 
      (let* ((start (- incr)) 
       (count start)) 
      (lambda num 
      (set! count (+ incr count)) count))))) 
     (if (null? num) 
     (temp 1) 
     (temp num))))) 

Это мой собственный код:

(define create-counter 
     (let ([count 0]) 
     (lambda ([x '()]) 
     (cond 
     [(null? x) (set! count (+ 1 count)) (- count 1)] 
     [(> x 0)(set! count (+ x count)) (- count x)]) 
    ))) 

Я понимаю, немного коротко о пусть и лямбда, как для закрытия ручки и такие. Однако для этой экстремальной проблемы я все еще не знаю, как писать, как пример кода. Мой код выполняет следующую работу:

(+ (create-counter 2) (create-counter 2) (create-counter 2) (create-counter 2)) -> 12 

Однако мой код не работает с образцами образцов. Я иногда получаю 0 или ошибки.

Что мне нужно изменить, чтобы исходный код мог работать и работать как образец? Пожалуйста, помогите мне лучше понять эту сферу и закрыть все, и все советы будут очень ценными. Спасибо и извините за мой плохой английский.

ответ

1

Код, который вы загрузили, излишне сложный.

Ваш лучше, но есть путаница в том, кто получает параметр, который указывает прирост. create-counter - это процедура, которая возвращает процедуру, но она является первой, которую вы хотите дать параметру, а не второй.

Кроме того, зачем работать со значением по умолчанию '(), когда вы можете использовать значение по умолчанию 1? Так что ваш код становится:

(define (create-counter (x 1)) 
    (let ([count 0]) 
    (lambda() 
     (set! count (+ x count)) 
     (- count x)))) 

Кстати ... вместо добавления x и снова вычитанием x, вы можете просто поставить начальное значение count во временную переменную и вернуть то, или просто использовать begin0:

(define (create-counter (incr 1)) 
    (let ((val 0)) 
    (lambda() 
     (begin0 
     val 
     (set! val (+ val incr)))))) 

или даже короче и с возможностью установить начальное значение на что-то другое, чем 0:

(define (create-counter (incr 1) (val 0)) 
    (lambda() 
    (begin0 
     val 
     (set! val (+ val incr))))) 

Тестирование:

> (let ((c (create-counter))) (+ (c) (c) (c) (c))) ; => 6 
6 
> (let ((c (create-counter 2))) (+ (c) (c) (c) (c))) ; => 12 
12 

Но это не работает для

(+ (create-counter 2) (create-counter 2) (create-counter 2) (create-counter 2)) ; -> 12 

так как здесь вы ожидаете create-counter вернуть числовое значение, когда на самом деле она возвращает процедуру.

+0

Есть ли эквивалентный код для «begin0»? С lambda() я всегда могу вернуть значение функции в закрытие, которое моя функция определяет, правильно ли? – kp2349

+0

Причина 'begin0' используется для возврата текущего значения счетчика, а затем последующего его повторения. Если вы не хотите использовать 'begin0', это будет выглядеть так: (λ() (let ((x val)) (set! Val (+ val incr)) x))' – naomik

+0

спасибо за объяснение я подробно. Я понял проблему сейчас. – kp2349