如果我有這樣的遞回函式:
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
我怎樣才能制作它的 lambda 版本而不給它一個名字?...就像我想在某處行內它一樣。那可能嗎?(我的意思是在這種情況下我可以使用 fold - 所以這個例子可能不是那么好) - 是否有某種我無法找到的“自我”符號或占位符?或者你只需??要給它一個名字。
uj5u.com熱心網友回復:
Racket 中的 Y-Combinator 是:
(lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
此函式可以采用任何匿名函式并遞回地將其應用于自身。
讓我們定義您的功能部分。double-n-times-部分僅用 lambda 撰寫:
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
f我們可以隨意命名的地方- 所以我們也可以稱之為double-n-part.
如果我們對此應用 Y-Combinator,我們得到:
((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
這會輸出一個函式,該函式接受引數x并將n第二個定義的內部函式應用于它們。
所以現在,沒有任何命名函式 - 僅使用lambda運算式 - 您可以應用您的引數 - 讓我們說x=3和n=4:
(((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda args (apply (g g) args))))))
(lambda (f)
(lambda (x n)
(if (= n 0) x (f (* 2 x) (- n 1))))))
3 4)
;;=> 48 ; as expected (3 * 2 * 2 * 2 * 2)
這樣讀起來更方便。但是我們也可以定義Y combinatorwithoutapply和argswhen 我們只允許一元函式(帶有一個引數的函式)而不是可變引數。然后它看起來像這樣(我們必須像這樣一個接一個地給出引數):
((((lambda (f)
((lambda (h) (h h))
(lambda (g) (f (lambda (x) ((g g) x))))))
(lambda (f)
(lambda (x)
(lambda (n)
(if (= n 0) x ((f (* 2 x)) (- n 1)))))))
3) 4)
;;=> 48
uj5u.com熱心網友回復:
通過使用宏,您的問題的答案是肯定的。但在我談論這個之前,我必須先問這個:你問是因為你只是好奇嗎?或者你問是因為有一些問題,比如你不想用名字污染命名空間?
如果您不想用名稱污染命名空間,您可以簡單地使用諸如 named let、letrec甚至 Y 組合器之類的本地結構。或者,你可以用define里面(let () ...)。
(let ()
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
(double-n-times 10 10))
;; double-n-times is not in scope here
對于實際答案:這是一個rlam類似于的宏lambda,但它允許您使用self來參考自身:
#lang racket
(require syntax/parse/define)
(define-syntax-parse-rule (rlam args body ... )
#:with self (datum->syntax this-syntax 'self)
(letrec ([self (λ args body ...)])
self))
;; compute factorial of 10
((rlam (x)
(if (= 0 x)
1
(* x (self (sub1 x))))) 10) ;=> 3628800
uj5u.com熱心網友回復:
是的。作為名稱的占位符是lambda 函式的引數的用途:
(define (double-n-times x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1))))
=
(define double-n-times (lambda (x n)
(if (= n 0)
x
(double-n-times (* 2 x) (- n 1)))))
=
(define double-n-times (lambda (self) ;; received here
(lambda (x n)
(if (= n 0)
x
(self (* 2 x) (- n 1)))))) ;; and used, here
但什么是這個“ self”引數?它是 lambda 函式本身:
= ;; this one's in error:
(define double-n-times ((lambda (u) ;; call self with self
(u u)) ;; to receive self as an argument
(lambda (self)
(lambda (x n)
(if (= n 0)
x
(self (* 2 x) (- n 1)))))))
;; can you see where and why?
= ;; this one isn't:
(define double-n-times ((lambda (u) (u u))
(lambda (self)
(lambda (x n)
(if (= n 0)
x
((self self) (* 2 x) (- n 1)))))))
;; need to call self with self to actually get that
;; (lambda (x n) ... ) thing to be applied to the values!
現在它起作用了:(double-n-times 1.5 2)回傳6.0。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/384447.html
上一篇:C中的遞回二項式系數
