Dr.racket kullanarak işlevsel bir programlama problemini çözme

Sep 24 2020

funPowerBir işlevi f, bir tamsayıyı alan nve işlevi döndüren adlı bir işlevi uygulamaya çalışıyorum f^n. Örneğin , olan 2((funPower sqrt 2) 16) döndürmelidir .(sqrt (sqrt 16))

Şimdiye kadar sahip olduğum şey bu ama bana doğru çıktı vermiyor

(define (funPower f n)
  (lambda(x) (if (<= n 1)
            (f x)
            (f (funPower f (- n 1)) x))))

Yanıtlar

2 WillNess Sep 25 2020 at 22:29

İlk olarak, bir çift parantez daha eksik.

(define (funPower1 f n)
  (lambda (x) (if (<= n 1)
            (f x)
         ;; (f (   funPower1 f (- n 1)) x))))
            (f ( ( funPower1 f (- n 1)) x)))) )
         ;;     ^^^                          ^^^

çünkü , örnekte de gösterdiğiniz gibi çağrılacak (funPower1 f (- n 1))bir işlevx , gelecekteki bağımsız değişken değerini döndürür .((funPower sqrt 2) 16)

İkincisi, öyle <= 0, değil <= 1ve fböyle bir durumda işlev hiç çağrılmamalıdır:

(define (funPower2 f n)
  (lambda (x) (if (<= n 0)
         ;; (f x)      ^^^
               x 
            (f ( ( funPower2 f (- n 1)) x)))) )

Şimdi işe yaradığına göre, kararları son çağrı zamanına ertelediğini görüyoruz ((funPower f n) x). Ama gerçekten tüm kararları önceden verebilir - nzaten biliniyor.

Bunu başarmak için, takas gerekiyor (lambdave (funPowerlambda itmek, "içinde" . Bunu yaptığımızda, bu kadar artırılmış için ek bir argüman olacak funPower:

(define (funPower3 f n)
  (if (<= n 0) (lambda (x) 
               x )
    (funPower3 f (- n 1) (lambda (x) (f x)))) )

Şimdi bu tamamen senkronize değil. Bu üçüncü tartışma nerede?

(define (funPower4 f n fun)
  (if (<= n 0) fun
    (funPower4 f (- n 1) (lambda (x) (fun (f x)))) ))

Bu biraz daha iyi, ama funaslen nedir? Nereden geliyor? Her zaman (lambda (x) x)ilk başta olmalı , yoksa doğru olmayacak. Çözüm, onu dahili bir tanım haline getirmek ve bunu kullanmak, ilk kez adlandırdığımızda doğru argümanı sağlamaktır:

(define (funPower5 f n)
  (define (loop n fun)
    (if (<= n 0) fun
      (loop (- n 1) 
            (lambda (x) (fun (f x))))))
  (loop n (lambda (x) x)))

Bu tür şeyler normalde adlandırılmış olarak kodlanır let,

(define (funPower5 f n)
  (let loop ((n  n) 
             (fun (lambda (x) x)))
    (if (<= n 0) fun
      (loop (- n 1) 
            (lambda (x) (fun (f x)))))))

Daha basit durumlarda daha basit işlevler oluşturmayı da deneyebiliriz. Örneğin, geri dönebilirler feğer kendisini nolduğunu 1:

(define (funPower6 f n)
  (cond 
    ((zero? n) .....)
    ((= n 1)   .....)
    ((< n 0)   .....)
    (else
      (let loop ((n  n) 
                 (fun .....))
        (if (= n .....) fun
          (loop (- n 1) 
            (lambda (x) (fun (f x)))))))))

Boşlukları doldurarak tamamlayın.

Daha önemli bir iyileştirme, hem sonuçta ortaya çıkan işlevi oluştururken hem de oluşturduğumuz işlev tarafından kullanılmasını sağlamak için tekrarlayan kareyi alarak üs alma kullanmaktır!

1 alinsoar Sep 25 2020 at 11:14

bunu dene:

(define funpow
  (lambda (f n)
    ((lambda (s) (s s n (lambda (x) x)))
     (lambda (s n o)
       (if (zero? n)
           o
           (s s (- n 1)
              (lambda (x)
                (o (f x)))))))))

    
(define sqrt_2 (funpow sqrt 2))
(define pow2_2 (funpow (lambda (x) (* x x)) 2))

(sqrt_2 16)
(pow2_2 2)