cond の代わりに if ステートメントを使用してこの関数を記述する方法はありますか? 以下は意図したとおりに機能しますが、別のオプションを知りたいと思っていました。
(define (harmonic-numbers n)
(cond ((= n 1) 1)
((> n 1) (+ (/ 1 n)
(harmonic-numbers(- n 1))))))
もちろん、 acond
は一連のネストされた s として実装できますif
。n
コードに潜在的なバグがあることに注意してください1
。
(define (harmonic-numbers n)
(if (= n 1)
1
(if (> n 1)
(+ (/ 1 n) (harmonic-numbers (- n 1)))
(error 'undefined))))
使用しているスキーム インタープリターによっては、if
すべての条件に対して常に "else" 部分を提供する必要がある場合があります (これが、n
が より小さい場合にエラーを通知した理由です1
)。他のインタープリターはそれほど厳密ではなく、喜んで片腕の条件を書くことができます:
(define (harmonic-numbers n)
(if (= n 1)
1
(if (> n 1)
(+ (/ 1 n) (harmonic-numbers (- n 1))))))
編集
n
が 1 未満の場合に何が起こるかを確立したので、次を使用してより単純なバージョンを記述できif
ます。
(define (harmonic-numbers n)
(if (<= n 1)
1
(+ (/ 1 n) (harmonic-numbers (- n 1)))))
を使用した同等のバージョンは次のcond
とおりです。
(define (harmonic-numbers n)
(cond ((<= n 1) 1)
(else (+ (/ 1 n) (harmonic-numbers (- n 1))))))
cond
R6RS 仕様ではDerived conditionalと呼ばれ、is のような必須の構文ではありませんif
。プリミティブとしては必須ではありませんが、マクロとして定義できます。以下は R5RS 仕様で定義されている cond の定義ですが、構文ケース マクロで定義されている current と互換性があります。
(define-syntax cond
(syntax-rules (else =>)
((cond (else result1 result2 ...))
(begin result1 result2 ...))
((cond (test => result))
(let ((temp test))
(if temp (result temp))))
((cond (test => result) clause1 clause2 ...)
(let ((temp test))
(if temp
(result temp)
(cond clause1 clause2 ...))))
((cond (test)) test)
((cond (test) clause1 clause2 ...)
(let ((temp test))
(if temp
temp
(cond clause1 clause2 ...))))
((cond (test result1 result2 ...))
(if test (begin result1 result2 ...)))
((cond (test result1 result2 ...)
clause1 clause2 ...)
(if test
(begin result1 result2 ...)
(cond clause1 clause2 ...)))))