考慮在λ
\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−
2),
n=1,
n=2,
n∈/
在λ\lambda
λ演算下我們設計成:
fib:=(λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2)))))
λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2))))))
例:(fib 5)值為5
我們發現,儘管上述的fib
函式在語義上,邏輯上都沒有問題,但寫起來比較繁瑣,不習慣。
一方面為簡化書寫,另一方面為符合習慣,我們考慮設計乙個函式,能讓以下這種寫法,自動轉換成完整的遞迴函式:
λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this (- n 1))
(this (- n 2)))))
我們設輸入函式為f
,輸出函式為g
f:=λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this (- n 1))
(this (- n 2)))))))
g:=(λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2)))))
λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2))))))
也就是說我們想要設計乙個函式,設為y
,它能做到:(y f)=g
那麼y
要怎麼設計呢?
觀察總結y
需要做的事情:
生成**將f
中的this
替換成(this this)
**的新函式,假設為f
返回將新函式自身傳遞給自身的函式,即返回(f f)
首先,生成**將f
中的this
替換成(this this)
**的新函式,可以這樣實現:
a:=λf.λthis.(f (this this))
(a f)
=λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2)))))))
其次,返回將新函式自身傳遞給自身的函式,可以這樣實現:
b:=λf.(f f)
(b (a f))
=((a f)
(a f))
=(λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2)))))
λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this this (- n 1))
(this this (- n 2))))))
=g即(b (a f))=g
所以y
就是:λf.(b (a f))
我們展開它:
λf.(b (a f))
=λf.(λf.(f f) (λf.λthis.(f (this this)) f))
=λf.(λf.(f f) λthis.(f (this this)))
=λf.(λthis.(f (this this)) λthis.(f (this this)))
=λf.(λx.(f (x x)) λx.(f (x x)))
得到y組合子:
y:=λf.(λx.(f (x x)) λx.(f (x x)))
有了它,現在我們可以這樣設計遞迴函式了:
fact:=(y λthis.λn.(if (= n 0) 1 (* n (this (- x 1)))))
fib:=(y λthis.λn.(if (= n 1)
1(if (= n 2)
1 (+ (this (- n 1))
(this (- n 2)))))
Lambda演算 簡述Y組合子的作用
y組合子 f.x.f xx x.f xx 接受乙個函式,返回乙個高階函式 y組合子用於生成匿名遞迴函式。什麼叫匿名遞迴函式,考慮以下c語言遞迴函式 int sum int n 這個函式在內部遞迴呼叫了自身,呼叫自身需要函式本體的名字,這個函式叫sum,sum內部用名字sum,遞迴呼叫了自己 在lam...
sed中y命令與s命令的區別
首先這兩個命令都可以用作替換,但替換時還是有區別的 1 y一般是行級別的替換,s一般是列級別替換 當然也可以轉換成行級 2 s替換的是整體,y替換的是每一字母對應的單個字母 例 1 sed s dog cat data 把data中的所有行中的第一次出現dog的替換成cat,注意 如果cat 後沒有...
java中的遞迴與階層
package com.jdbk.www public class testdigui static int count 0 static void a else 計算10的階層 static void b static long factorial int n else 測試普通迴圈費時與遞迴差距...