邱奇數

邱奇編碼是把數據和運算符嵌入到lambda演算內的一種方式，最常見的形式即邱奇數，它使用lambda符號表示自然數。方法得名於阿隆佐·邱奇，他首先以這種方法把數據編碼到lambda演算中。
透過邱奇編碼，在其他符號系統中通常被認定為基本的項（比如整數、布爾值、有序對、列表和tagged unions）都會被映射到高階函數。在無型別lambda演算，函數是唯一的原始型別。
邱奇編碼本身並非用來實踐原始型別，而是透過它來展現我們不須額外原始型別即可表達計算。
很多學數學的學生熟悉可計算函數集合的哥德爾編號；邱奇編碼是定義在lambda抽象而不是自然數上的等價運算。

**用途**
直接實現邱奇編碼會將某些訪問操作的時間複雜度從降低到（其中是數據結構的大小），這使得該編碼方式在實際應用中受到限制。研究表明可以通過針對性優化解決這個問題，但大多數函數式編程語言選擇擴展其中間表示以包含代數數據類型。
儘管如此，邱奇編碼仍常用於理論論證，因為它在部分求值和定理證明中具有自然表示優勢。通過使用高階類型可以對操作進行類型標註，並能便捷地實現原始遞歸。由於函數被假定為唯一的原始數據類型，這種設定簡化了許多證明過程。
邱奇編碼具有表示完整性但僅限於表徵層面。需要額外函數將這種表示轉換為通用數據類型以供人工解讀。由於邱奇定理中等價性不可判定，通常無法判斷兩個函數是否具有外延等價性。轉換過程可能需要通過某種方式應用函數來提取其表徵值，或者以λ項字面量的形式查找其值。λ演算通常被解釋為使用內涵等價性。由於等價性的內涵定義與外延定義存在差異，在結果解釋方面可能存在潛在問題。

**邱奇數**
邱奇數為使用邱奇編碼的自然數表示法，而用以表示自然數的高階函數是個任意函數映射到它自身的n重函數複合之函數，簡言之，數的「值」即等價於參數被函數包裹的次數。

不論邱奇數為何，其都是接受兩個參數的函數。邱奇數0、1、2、... 在λ演算中的定義如下：
從 0 不應用函數開始， 1 應用函數一次， 2 應用函數兩次， 3 應用函數三次，依此類推：

邱奇數3表示對任意給定函數應用三次的操作。當輸入函數被提供時，首先應用於初始參數，然後連續應用於自身結果。最終結果並非數字3（除非初始參數恰好為0且函數為後繼函數）。邱奇數3的本質是函數的應用次數，而非計算結果本身。其核心意義在於「重複三次」的動作，這正是「三次」概念的直觀體現。
就是說，自然數被表示為邱奇數n，它對於任何lambda-項F和X有著性質：
 n F X =β Fn X。

**使用邱奇數的計算**
在 lambda 演算中，數值函數被表示為在邱奇數上的相應函數。這些函數在大多數函數式語言中可以通過 lambda 項的直接變換來實現（服從於類型約束）（請參閱將lambda表達式轉換為函數）。
加法函數  利用了恆等式 。
 
後繼函數  β-等價於（plus 1）。
 
乘法函數  利用了恆等式 。
 
指數函數  通過邱奇數定義給出：將定義中的和代入可得，因此：
 
對應的lambda表達式為：
 
前驅函數  的實現較為複雜：
 
邱奇數通過n次應用函數來運作。前驅函數需要返回一個應用參數n-1次的函數。這通過構建包含f和x的容器來實現，該容器以省略第一次函數應用的方式初始化（詳見前驅函數推導）。
基於前驅函數可定義減法函數：
 

**邱奇數函數一表**
注意：

**前驅函數推導**
邱奇編碼中使用的前驅函數定義為：

為了減少一次函數應用次數來構造前驅函數，需採用容器函數封裝值。定義新函數 inc 和 init 替代原函數f和參數x，其中容器函數稱為value。下表左側展示了邱奇數n作用於inc和init的情況：

通用遞歸規則為：

若定義從容器中提取值的函數extract：

則可構造同數函數samenum：
 
通過將init替換為特殊容器const（該容器首次調用時忽略參數以跳過第一次函數應用），可推導前驅函數：
 
具體函數定義如下：

最終得到前驅函數的lambda表達式：
 

**前驅函數的另一種解釋**
使用組合子符號可簡化前驅函數的解釋：
  
  
  
  
通過下列推導可驗證其正確性：
 
 
 
通過eta-歸約和歸納法可得：
 
 
 

**前驅函數的另一種定義**
使用序對可定義前驅函數：

此定義雖簡潔但展開式較複雜，以為例：


**除法函式**
自然數除法可通過以下方式實現：
 
計算需要多次beta歸約。除非手動進行歸約，否則這並不重要，但最好避免重複計算。最簡單的數值檢測謂詞是IsZero，故考慮條件：
 
此條件等價於而非。若採用該條件，則上述數學定義可轉化為邱奇數函數：
 
此定義僅調用一次，但結果為此公式給出的是的值。
通過給n加1後調用divide可修正該問題，定義式為：
 
divide1為遞歸定義，需用Y組合子實現遞歸。通過以下步驟創建新函數div：- 左側替換：- 右側替換：
得到：
 
完整定義式為：

其中：
 
: 
 
最終展開式：
 
以文本格式表示（用\代替λ）：
divide = (\n.((\f.(\x.x x) (\x.f (x x))) (\c.\n.\m.\f.\x.(\d.(\n.n (\x.(\a.\b.b)) (\a.\b.a)) d ((\f.\x.x) f x) (f (c d m f x))) ((\m.\n.n (\n.\f.\x.n (\g.\h.h (g f)) (\u.x) (\u.u)) m) n m))) ((\n.\f.\x. f (n f x)) n))
例如，9/3可表示為：
divide (\f.\x.f (f (f (f (f (f (f (f (f x))))))))) (\f.\x.f (f (f x)))
使用lambda演算計算器，按正規順序歸約後結果為3：
\f.\x.f (f (f (x)))

**有符號數**
通過使用包含正負值的邱奇序對，可將邱奇數擴展至有符號數。整數值即兩個邱奇數的差值。
自然數轉有符號數的定義為：

取反操作通過交換序對元素實現：

當序對中某一元素為零時，整數表示更自然。OneZero函數確保該條件：

使用Y組合子實現遞歸：



**加減運算**
加法數學定義為：

對應lambda表達式：

減法定義為：

對應lambda表達式：


**乘除運算**
乘法定義為：

對應lambda表達式：

除法需確保序對元素含零（見上文的OneZero），定義輔助函數：

除法表達式：


**有理數與實數**
有理數可表示為有符號數序對，可計算實數可通過極限過程編碼。複數可自然地表示為實數序對。上述數據類型驗證了邱奇-圖靈論題：任何數據類型或計算均可編碼於lambda演算中。

**換成其它表達法**
大部分真實世界的程式語言都提供原生於機器的整數，church 與 unchurch 函式會在整數及與之對應的邱奇數間轉換。這裡使用Haskell撰寫函式， \ 等同於lambda演算的 λ。 用其它語言表達也會很類似。
type Church a = (a -> a) -> a -> a
church :: Integer -> Church Integer
church 0 = \f -> \x -> x
church n = \f -> \x -> f (church (n-1) f x)
unchurch :: Church Integer -> Integer
unchurch cn = cn (+ 1) 0

**邱奇布爾值**
邱奇布爾值是布爾值真和假的邱奇編碼形式。某些程式語言使用這個方式來實踐布爾算術的模型，Smalltalk和Pico即為典型示例。
布爾邏輯本質上是選擇機制。邱奇布爾值的編碼形式為接收兩個參數的函數：- 真（true）選擇第一個參數- 假（false）選擇第二個參數
其標準定義為：
 
這種編碼允許謂詞函數（返回邏輯值的函數）直接作為條件語句使用。當布爾函數作用於兩個參數時，將根據真值返回其中一個參數：
 
若predicate-x為真則返回then-clause，否則返回else-clause。
由於真值與假值的選擇特性，它們可組合出各類邏輯運算符。需注意邏輯非not存在多種實現方式：
 
註：
*1 求值策略使用應用次序時，這個方法才正確。
*2 求值策略使用正常次序時，這個方法才正確。
運算示例解析：
 

**謂詞**
謂詞是返回布爾值的函數。最基礎的謂詞是，當其參數為邱奇數時返回，否則返回：
 
下列謂詞檢測第一個參數是否小於等於第二個參數：
 
基於恆等關係：
 
相等性檢測可定義為：
 

**邱奇序對**
邱奇序對是二元組的邱奇編碼實現。序對被表示為接收函數的函數，當傳入參數時會將該參數作用於序對的兩個分量。其lambda演算定義為：
 
示例推導：
 

**列表編碼**
不可變的列表由列表節點構成，其基本操作包括：
以下給出四種不同的列表表示法：- 使用雙序對構造列表節點（支持空列表）- 使用單序對構造列表節點- 基於右摺疊函數的列表表示- 採用Scott編碼的模式匹配參數化表示

**雙序對列表節點**
非空列表可用邱奇序對錶示：- First 存儲首元素- Second 存儲尾部
為支持空列表，需額外包裹序對形成三層結構：- First - 空列表標識符- Second.First 存儲首元素- Second.Second 存儲尾部
基於此的核心操作定義如下：
注意：當列表為空時，head和tail函數不應被調用。

**單序對列表節點**
另一種定義方式PDF版本：access-date=2017-11-24：
 
通用處理模板定義為：
 
其他擴展操作：
 
----
 
----
 
----
 

**右摺疊列表表示**
作為邱奇序對編碼的替代方案，列表可通過其右摺疊函數進行編碼。例如，包含三個元素x、y、z的列表可編碼為高階函數，當該函數應用組合子c和初始值n時，返回c x (c y (c z n))。這等價於部分應用函數組合鏈的調用：(c x ∘ c y ∘ c z) n。
 
此列表表示可在系統F類型系統中定義。
與邱奇數的對應關係並非巧合，邱奇數本質上是單元值列表（如() () ()）的一進制編碼，列表長度即表示自然數值。對此類列表進行右摺疊時，組合函數忽略元素值，其本質與邱奇數中的函數組合鏈（即(c () ∘ c () ∘ c ()) n = (f ∘ f ∘ f) n）具有等價性。

**Scott編碼列表表示**
另一種實現方式是採用Scott編碼，這種方式能生成更簡潔的代碼（參見摩根森-斯科特編碼）。
該編碼的核心思想是利用模式匹配的特性。以Scala語法為例，假設list表示包含空列表Nil和構造器Cons(h, t)的列表類型，可通過模式匹配進行計算：
list match {
case Nil        => nilCode
case Cons(h, t) => consCode(h,t)
}
列表的行為由其模式匹配決定，因此可將列表定義為接收nilCode和consCode參數的函數：
 
設n對應空列表處理參數，c對應非空列表處理參數，則：
空列表定義為：
 
非空列表（含首元素h和尾部t）定義為：
 
更一般地，包含種構造器的代數數據類型將被編碼為具有個參數的函數。當第個構造器包含個參數時，對應編碼參數也接收個參數。
該編碼可在無類型λ演算中使用，但帶類型版本需支持遞歸和類型多態的系統。以元素類型E、計算結果類型C的列表為例，其遞歸類型定義為（"=>"表示函數類型）：
type List =
C =>                    // 空列表分支
(E => List => C) =>     // 非空列表分支
C                       // 模式匹配結果
支持任意計算類型的列表需量化類型C，而泛型列表還需將元素類型E作為類型參數。

**參見**
Lambda演算
*系統F，在有類型lambda演算中的邱奇數

**外部鏈接**
 Some interactive examples of Church numerals date=20060512015859