2016-07-13 9 views
0

В упражнении SICP 1.37Не можете понять, как мы можем дать процедуры как фактический параметр, когда формальные параметры используются в качестве значений в схеме?

Section 1.3.3 in SICP Прокрутите вниз до конца раздела (непосредственно перед 1.3.4), чтобы найти упражнение [3-е упражнение в разделе].

По этой проблеме, я определил прод-гидроразрыва в

(define (cont-frac n d k) 
    (if (= k 0) 
    0 
    (/ n (+ d (cont-frac n d (- k 1)))) 
    ) 
) 

Link to solution for the exercise

Согласно решению связать приведенный выше код, кажется, быть последовательным. Проблема возникает во второй части раствора, когда n и d заменяются как (lamda (i) 1.0), частью (а) решения, которое является процедурой.

Я не могу понять, как это будет работать при замене в процедуре cont-frac. Когда я попробовал, есть ошибка, которая говорит Неверный тип аргумента


Edit 1

Я добавил все мое решение. Он решает проблему, но не отражает суть раздела. Это решение упражнений 1.37, 1.38 и 1.39. Программа не использует процедуры, как общий метод, какие решений по ссылкам ниже делать Solution to 1.37, Solution to 1.38 и Solution to 1.39

В приведенной ниже программе
в процедурах phi и e-2-val, к не из шагов по-прежнему фракция
в процедуре tan, к пока угол в радианах (нет шагов 1000 за точное значение)

#!/usr/local/bin/guile \ 
-e main -s 
!# 
(define (finite-cont-frac n d k) 
    (if (= k 0) 
     0 
     (/ n (+ d (finite-cont-frac n d (- k 1)))))) 

(define (e-2 n d k1 c k) 
    (define (d-val) 
     (if (= (modulo k1 3) 1) 
      (+ c 2) 
      1)) 
    (define (c-val) 
     (if (= (d-val) 1) c (d-val))) 
    (if (= k 0) 
     0 
     (/ n (+ (d-val) (e-2 n (d-val) (+ k1 1) (c-val) (- k 1)))))) 

(define (tan-cf n k d k1) 
    (define (d-val) 
     (if (= k1 0) 1 (+ d 2))) 
    (if (= k 0) 
     0 
     (/ n (+ (d-val) (tan-cf n (- k 1) (d-val) (+ k1 1)))))) 

(define (tan-man x kk) 
    (let ((a (- (* x x)))) 
     (tan-cf a kk 1 0))) 
(define rrr 80.0) 
(define (main args) 
    (let* ((k (string->number (list-ref args 1))) 
      (phi (/ 1.0 (finite-cont-frac 1.0 1.0 k))) 
      (e-2-val (e-2 1.0 1 0.0 0 k)) 
      (tt (/ (tan-man k 1000) (- 0.0 k)))) 
     (display tt) 
     (newline))) 

+0

Обратите внимание, что закрытие скобок не должно быть на их собственной линии, как C фигурной скобкой программирования. Они должны быть на линии выше рядом с последней закрывающей скобкой. – Sylwester

+0

Это как идиоматическое правило? Потому что это не дает никакой ошибки. –

+1

* TL; DR Это консенсус. * Это правда, что это не влияет на интерпретации. У вас может быть один символ или скобка на каждой строке, что делает ваш пример длиной в несколько страниц нечитаемым, но вполне исполняемым кодом. Lisp имеет очень мало структуры в своем коде, поэтому, как вы создаете код, как вы делаете его читабельным. Существуют [руководства по стилям] (http://mumble.net/~campbell/scheme/style.txt), в которых lispers соглашаются и вопросы об этом на [PSE] (http://programmers.stackexchange.com/questions/99229/why-does-the-lisp-community-prefer-to-accumulate-all-the-parentheses-at-the-end) – Sylwester

ответ

1

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

(define (accumulate combiner null-value term1 term2 a next b) 
    (if (> a b) 
     null-value 
     (combiner (term1 a) 
       (term2 a) 
       (accumulate combiner 
          null-value 
          term1 
          term2 
          (next a) 
          next 
          b)))) 

(define (cont-frac n d k) 
    (accumulate (λ (x y rec) (/ x (+ y rec))) 
       0 n d 1 add1 k)) 

Теперь мы можем назвать процедуру, как и ожидалось:

(cont-frac (lambda (i) 1.0) 
      (lambda (i) 1.0) 
      10) 
=> 0.6179775280898876 
+0

Я только что понял, какую ошибку сделал я, и вернулся в stackoverflow, чтобы удалить вопрос. Спасибо за решение, хотя. –

+0

Связанный ответ правильный. Мое решение не подходит для раздела. Мое решение не является чем-то неправильным, но решение в ссылке использует n и d как процедуры, передающие k в качестве параметра. Решение в ссылке очень обобщено, мне пришлось написать много других процедур для определения n и d в упражнениях 1.38 и 1.39, но с использованием обобщенного решения ссылки достаточно было пропустить λ функции. –