Trong -calculus, chúng ta có thể mã hóa số học, số, booleans và thậm chí tính các yếu tố của các số, như được hiển thị ở đây .
Có mã hóa "cho" hoặc "trong khi" không?
Trong -calculus, chúng ta có thể mã hóa số học, số, booleans và thậm chí tính các yếu tố của các số, như được hiển thị ở đây .
Có mã hóa "cho" hoặc "trong khi" không?
Câu trả lời:
Chắc chắn rồi! Hãy để tôi chỉ cho bạn cách mã hóa FOR bằng cách sử dụng một ví dụ.
Giả sử chúng ta muốn dịch một giai thừa cho chương trình đơn giản
x := 1
for i := 1 to N do
x := x * i
Chúng tôi viết lại như là
x := 1
i := 1
repeat N times
x := x*i
i := i+1
sau đó chúng tôi đặt tất cả các biến chúng tôi sử dụng trong một tuple (một cặp đủ ở đây)
(x,i) := (1,1)
repeat N times
(x,i) := (x*i, i+1)
Điều này áp dụng hiệu quả chức năng cho cặp ban đầu trong lần.
Vì có thể được biểu diễn dưới dạng số của Giáo hội, chúng tôi nhận được
Cú pháp trên sử dụng một vài điều ngoài phép tính lambda đơn giản. Số và số học có thể được thực hiện chính xác bằng cách sử dụng chữ số Church. Các cặp cũng có mã hóa Giáo hội riêng:
Nếu bạn có nhiều hơn hai biến, bạn có thể khái quát mã hóa ở trên thành các bộ dữ liệu hoặc chỉ đơn giản biểu thị các bộ dữ liệu dưới dạng các cặp lồng nhau.
WHILE được xử lý tốt nhất bằng cách sử dụng đệ quy: thay vì
while p(x,i) do
(x,i) := f(x,i)
trong đó p
là một vị ngữ và f
là một số hàm (một phần), chúng ta có thể sử dụng một cái gì đó như
def recFun(x,i):
if p(x,i):
return recFun(f(x,i))
else:
return (x,i)
Trong phép tính lambda, đệ quy thu được bằng cách sử dụng một tổ hợp điểm cố định , ví dụ: Church's hoặc Turing's . Chúng tôi nhận được một cái gì đó như
trong đó giả sử booleans được mã hóa Church.
Cũng lưu ý rằng WHILE (nghiêm túc) mạnh hơn FOR. Mỗi FOR có thể được mã hóa dưới dạng WHILE, vì vậy kỹ thuật mã hóa này cũng có thể được sử dụng cho FOR.
Có các mã hóa các vòng lặp, nhưng chúng không hoạt động chính xác như các vòng lặp mà bạn đã từng sử dụng, vì phép tính lambda không phải là một ngôn ngữ bắt buộc. Tính toán lambda không có tác dụng phụ (đó là ngôn ngữ hoàn toàn chức năng ), do đó, tương đương chính xác của một vòng lặp sẽ là vô ích.
Một chương trình bắt buộc có thể được dịch sang một ngôn ngữ chức năng thuần túy bằng cách chuyển tất cả trạng thái xung quanh một cách rõ ràng như một biến trong chương trình. Tôi sẽ sử dụng cú pháp Python cho mã giả bắt buộc; nó phải gần như trong suốt, với dấu hiệu (a, b) = f(…)
có nghĩa là lệnh gọi hàm f
trả về một cặp a
và b
được gán thành phần thứ nhất và thứ hai của cặp tương ứng. Xem xét một vòng lặp
while test_condition():
do_stuff()
Hãy làm cho nhà nước rõ ràng.
state = initial_state
(state, cond) = test_condition(state)
while cond:
(state, cond) = test_condition(do_stuff(state))
Chúng ta có thể dịch nó thành một cuộc gọi đệ quy. def loop(state):
định nghĩa một hàm gọi là loop
.
def loop(state):
(state, cond) = test_condition(state)
if cond: return loop(do_stuff(state))
else: return state
state = loop(initial_state)
Điều này chỉ sử dụng các khái niệm sau, tất cả đều có thể được biểu thị dễ dàng trong phép tính lambda:
Và do đó chúng ta có thể định nghĩa một while
hàm cho một điều kiện( test_condition
) và một cơ thể( do_stuff
):
Đối với các vòng lặp khác nhau tùy thuộc vào ngôn ngữ lập trình, nhưng chúng luôn là trường hợp đặc biệt của các vòng lặp trong khi chúng có thể được mã hóa theo cùng một cách. Nếu ngôn ngữ nguồn giới hạn tính biểu cảm của các vòng lặp, có thể có các bảng mã đơn giản hơn. Ví dụ, lặp lại thời gian đơn giản là thành phần chức năng lần, trong đó hàm là phép biến đổi trạng thái cấu thành phần thân của vòng lặp và nếu là một con số của Giáo hội, điều đó chỉ đơn giản là áp dụng chính nó để các chức năng cơ thể vòng lặp.
Một cách tiếp cận khác với trạng thái là mở rộng phép tính lambda với các nguyên hàm thao tác trạng thái. Nếu bạn làm điều đó, thứ tự đánh giá trở nên quan trọng. Trong trường hợp đó, một vòng lặp while có thể được biểu thị trực tiếp bằng đệ quy.