2013-05-30 4 views
0

Когда я набрал свое оригинальное решение подзадачи b. упражнения 2.29 в SICP:SICP Exercise 2.29 Confusion

(define (total-weight m) 
    (let ((left (left-branch m)) 
     (right (right-branch m))) 
    (cond ((null? m) 0) 
      ((not (pair? m)) m) 
      (else 
      (+ (total-weight (branch-structure left)) 
       (total-weight (branch-structure right))))))) 

и проверили его со следующими данными:

(define left1 (make-branch 5 8)) 
(define right1 (make-branch 7 10)) 
(define m1 (make-mobile left1 right1)) 
(define right2 (make-branch 1 3)) 
(define m2 (make-mobile left2 right2)) 
(define left0 (make-branch 12 m1)) 
(define right0 (make-branch 5 m2)) 
(define m0 (make-mobile left0 right0)) 
(total-weight m0) 

Интерпретатор (MIT/ГНУ Схема) сообщила об ошибке: «объект 3, который передается в качестве первого аргумента cdr, не является правильным типом ». Но когда я устранил выражение

(let ((left (left-branch m)) 
     (right (right-branch m))) 
    ...) 

со следующим кодом:

(define (total-weight m) 
    (cond ((null? m) 0) 
     ((not (pair? m)) m) 
     (else 
     (+ (total-weight (branch-structure (left-branch m))) 
      (total-weight (branch-structure (right-branch m))))))) 

программа работала отлично и напечатал результат

;Value: 27 

я запутался. Кто-нибудь может судить об этой проблеме и помочь мне?

+0

две версии эквивалентны. –

+0

@WW Кроме того, что в версии, использующей 'let',' m', используется до ее тестирования. –

+0

@TerjeD. Я пойду съеду свой скромный пирог. :) –

ответ

4

Проблема заключается в том, что в первой версии, (left-branch m) и (right-branch m) вызывается, прежде чем проверить m является ли или нет мобильного телефона. то есть m может быть число или nil.

+0

Это имеет смысл! Без вашей помощи мне было бы долгим периодом узнать этот недостаток моего понимания «пусть». Большое вам спасибо, теплый мальчик! :-) –