5

私はTheSeasonedSchemerを読んでいて、長さ関数のこの定義に出くわしました

(define length
  (let ((h (lambda (l) 0)))
    (set! h (L (lambda (arg) (h arg))))
    h))

後で彼らは言う:

(L(lambda(arg)(h arg)))の値は何ですか?機能です

(lambda (l)
  (cond ((null? l) 0)
     (else (add1 ((lambda (arg) (h arg)) (cdr l))))))

私はこれを完全には理解していないと思います。私たちは自分たちをエクササイズとして定義することになっていると思います。私はletrecを使用して長さの定義内にLの定義を書きました。これが私が書いたものです:

(define length
  (let ((h (lambda (l) 0)))
    (letrec ((L
              (lambda (f)
                (letrec ((LR
                          (lambda (l)
                            (cond ((null? l) 0)
                                  (else
                                   (+ 1 (LR (cdr l))))))))
                  LR))))                  
    (set! h (L (lambda (arg) (h arg))))
    h)))

したがって、Lは引数として関数を取り、値としてリストを引数として取り、リストに対して再帰を実行する別の関数を返します。私の解釈は正しいですか、それとも絶望的に間違っていますか?とにかく定義は機能します

 (length (list 1 2 3 4))  => 4
4

1 に答える 1

3

「TheSeasonedSchemer」ではlength、最初は次のように定義されています。

(define length
  (let ((h (lambda (l) 0)))
    (set! h (lambda (l)
              (if (null? l)
                  0
                  (add1 (h (cdr l))))))
    h))

この本の後半で、前の結果が一般化され、次のように(適用順序、命令型Yコンビネータ)のlength観点から再定義されます。Y!

(define Y!
  (lambda (L)
    (let ((h (lambda (l) 0)))
      (set! h (L (lambda (arg) (h arg))))
      h)))

(define L
  (lambda (length)
    (lambda (l)
      (if (null? l)
          0
          (add1 (length (cdr l)))))))

(define length (Y! L))

質問に示されているの最初の定義はlength、単なる中間ステップLです。上記で定義された手順を使用すると、再定義する必要はありません。この章のこの部分の目的は、私の答えに示されている2番目の定義に到達することです。

于 2012-06-14T16:43:57.410 に答える