1
(define wadd (lambda (i L)
                (if (null? L) 0
                    (+ i (car L)))
                    (set! i (+ i (car L)))
                          (set! L (cdr L))))

(wadd 9 '(1 2 3))

これは何も返しません。私はそれがすることを期待しています(3 + (2 + (9 + 1))、それはに等しいはず15です。私set!は間違った方法を使用していますか?条件set!内で電話できませんか?if

4

2 に答える 2

3

あなたのコードから、あなたが何らかの形でリストをトラバースするつもりだったと推測しますが、リストwaddを反復処理するプロシージャには何もありません-再帰呼び出し、ループ命令、何もありません:誤用された条件とset!1回だけ実行されるいくつかのs 。私は質問の手順を修正しようとはしません、修理を超えています-私はむしろ問題を解決する正しい方法をあなたに示したいと思います。あなたはこれらの線に沿って何かが欲しいです:

(define wadd
  (lambda (i L)
    (let loop ((L L)
               (acc i))
      (if (null? L)
          acc
          (loop (cdr L) (+ (car L) acc))))))

実行されると、前のプロシージャはこの式を評価します:次(wadd 9 '(1 2 3))のように: (+ 3 (+ 2 (+ 1 9)))。@Maxwellが指摘しているように、上記の操作はfoldlを使用してより簡潔に表現できることに注意してください

(define wadd
  (lambda (i L)
    (foldl + i L)))

原則として、Schemeset!では、命令型のCのような言語の場合ほど頻繁に割り当て(命令)を使用することはありません。関数型プログラミングスタイルが推奨されます。これは、再帰と操作に大きく依存します。状態を変更します。

于 2013-01-09T04:59:56.777 に答える
2

インデントを修正すると、問題がより明確になると思います。

関数set!は戻ります<#void>(または同様の無意味なもの)。ラムダwaddは次のことを行います。

  1. がnullかどうかを確認Lし、0またはi+(car L)と評価してから、結果を破棄します。
  2. 変更iして何も評価しない
  3. 変更Lして何も返さない

複数のステートメントをラムダに入れると、それらはbegin明示的にステートメントにラップされます。

(lambda () 1 2 3) => (lambda () (begin 1 2 3))

シーケンス内の複数の式のbeginステートメントでは、全体beginが最後のステートメントの結果に評価されます。

(begin 1 2 3) => 3
于 2013-01-09T03:44:50.543 に答える