Lambda演算 簡述Y組合子的作用

2022-07-27 01:09:12 字數 1096 閱讀 4197

y組合子:\f.(\x.f(xx))(\x.f(xx)),接受乙個函式,返回乙個高階函式

y組合子用於生成匿名遞迴函式。

什麼叫匿名遞迴函式,考慮以下c語言遞迴函式

int sum(int n)

這個函式在內部遞迴呼叫了自身,呼叫自身需要函式本體的名字,這個函式叫sum,sum內部用名字sum,遞迴呼叫了自己

在lambda演算中,可以寫成類似的表示式sum = \x. x == 0 ? 0 : sum x

但是對於乙個lambda表示式,他本身是匿名的,lambda在定義的過程中引用了自身,就算是c++,這樣的lambda表示式也是不成立的

auto sum = (int n) ;
lambda表示式本身是不具名的,我們需要繞開這個限制。

一種可能的解決辦法是使用高階函式,用另乙個函式把上面的sum包裝一下:它接受乙個函式f,並返回乙個函式,這個函式接受x,判斷遞迴終點,或呼叫f繼續遞迴:

g = \f. \x. x == 0 ? 0 : f (x-1)

寫成c++是這樣的

auto g = (functionf) ;

};

現在我們發現,當有乙個函式f使得g(f) = (int x) = f的時候,這個f正好是我們需要的匿名遞迴函式sum

g(f) = f,眼熟嗎,還記得不動點這個概念嗎,我們需要的匿名遞迴函式sum就是函式g的不動點

求解這個不動點sum,我們即可獲得乙個匿名遞迴函式,如何求解見附

最後的結果:sum = yg,y和g前面已知,這樣,sum是乙個簽名為int(int)的函式,是乙個匿名遞迴函式

y組合子也稱不動點組合子,用這個方法可以求解一切匿名遞迴函式。

附:sum = yg使得g(sum) = sum的證明:

證明:對於任意g,g(yg) = yg

令w = \x. g(xx), x = ww //這個令真的太tm絕了,反正我是沒想到

有x = ww = (\x. g(xx))w = g(ww) = g(x)

又因為yg = (\x. g(xx))(\x. g(xx)) = ww = x

所以g(x) = x就是g(yg) = yg

證畢

lambda演算中的遞迴與Y組合子

考慮在 lambda 演算中實現乙個遞迴的階乘函式,f ac t n 1 n 0 n cdot fact n 1 n neq0 end fact n fib n begin 1 n 1 1 n 2 fib n 1 fib n 2 n notin end fib n 1 1fib n 1 fi b n...

Racket中使用Y組合子

關於y組合子,網上已經介紹很多了,其作用主要是解決匿名lambda的遞迴呼叫自己。首先我們來看直觀的遞迴lambda定義,假設要定義階乘的lambda表達,c 中需要這麼定義 func fact null fact x x 1 1 x fact x 1 這種方法非常簡單直接,當然問題也存在,因為這裡...

演算法 回溯求排列組合,子集問題的總結

leetcode上有許多用回溯求排列組合,子集的題目 leetcode46 leetcode47 我的思路可看這裡 leetcode77 我的思路可看這裡 leetcode39 leetcode40 leetcode216 leetcode78 leetcode90 我的思路可看這裡 總結一下 用回...