コードにいくつかの概念上の問題があります。私は@itsbruceに同意します。質問で見つかった各エラーを修正するよりも、正しい解決策の方法であなたを指摘する方が簡単です。
まず、プロシージャは既存の高階関数の観点から記述できることに注意してください。foldr
値を累積し、値build-list
の範囲を作成します。
(define (accumulate-interval op init lower upper)
(foldr op init
(build-list (add1 (- upper lower))
(lambda (x) (+ lower x)))))
または、Racketfor/list
で、値の範囲を作成するために使用できます。
(define (accumulate-interval op init lower upper)
(foldr op init
(for/list ([n (in-range lower (add1 upper))]) n)))
ソリューションを最初から作成する必要がある場合(おそらくそうです)、問題を部分に分割することをお勧めします。まず、数値の範囲を生成します。
(define (range lower upper)
(if (> lower upper)
'()
(cons lower
(range (add1 lower) upper))))
ここで、値を累積します。
(define (accumulate op init lst)
(if (null? lst)
init
(op (car lst)
(accumulate op init (cdr lst)))))
最後に、前の2つのヘルパー手順を組み合わせて問題の解決策を作成します。最初の2つのソリューションでは、まったく同じ問題分解(最初:範囲の生成、2番目:累積、3番目:結合)を行ったことに注意してください。唯一の違いは、既存の手順を使用する代わりに、ヘルパー手順を手動で記述したことです。
(define (accumulate-interval op init lower upper)
(accumulate op init
(range lower upper)))
もちろん、ソリューションのようにすべての手順を1つにマージすることもできます。これは、数値の中間リストを作成しないため、より効率的です。
(define (accumulate-interval op init lower upper)
(if (> lower upper)
init
(op lower
(accumulate-interval op init (add1 lower) upper))))
...しかし、そうすることで、他のコンテキストで役立つ一連の構成可能な手順ではなく、1つの特定の問題に対してカスタマイズされたソリューションが生成されます。関数型プログラミングスタイルでは、ジェネリックで再利用可能な関数を定義することが推奨されます。
とにかく、これは期待どおりに機能します。
(accumulate-interval + 0 2 4)
> 9
(accumulate-interval * 1 2 5)
> 120