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

2021-10-02 05:55:09 字數 2863 閱讀 8037

考慮在λ

\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 測試普通迴圈費時與遞迴差距...