Lạm dụng đại số của các loại dữ liệu đại số - tại sao điều này hoạt động?


289

Biểu thức 'đại số' cho các kiểu dữ liệu đại số trông rất gợi cho người có nền tảng toán học. Hãy để tôi cố gắng giải thích những gì tôi có ý nghĩa.

Đã xác định các loại cơ bản

  • Sản phẩm
  • liên hiệp +
  • Người độc thân X
  • Đơn vị 1

và sử dụng tốc ký cho X•X2Xcho X+Xet cetera, sau đó chúng ta có thể định nghĩa các biểu thức đại số cho các danh sách được liên kết

data List a = Nil | Cons a (List a)L = 1 + X • L

và cây nhị phân:

data Tree a = Nil | Branch a (Tree a) (Tree a)T = 1 + X • T²

Bây giờ, bản năng đầu tiên của tôi là một nhà toán học là phát điên với những biểu thức này, và cố gắng giải quyết LT. Tôi có thể làm điều này thông qua sự thay thế lặp đi lặp lại, nhưng có vẻ dễ dàng hơn nhiều để lạm dụng ký hiệu một cách khủng khiếp và giả vờ rằng tôi có thể sắp xếp lại nó theo ý muốn. Ví dụ: đối với danh sách được liên kết:

L = 1 + X • L

(1 - X) • L = 1

L = 1 / (1 - X) = 1 + X + X² + X³ + ...

trong đó tôi đã sử dụng việc mở rộng chuỗi 1 / (1 - X)lũy thừa theo cách hoàn toàn không chính đáng để thu được một kết quả thú vị, cụ thể là một Lloại Nilhoặc là chứa 1 phần tử hoặc chứa 2 phần tử hoặc 3, v.v.

Sẽ thú vị hơn nếu chúng ta làm điều đó cho cây nhị phân:

T = 1 + X • T²

X • T² - T + 1 = 0

T = (1 - √(1 - 4 • X)) / (2 • X)

T = 1 + X + 2 • X² + 5 • X³ + 14 • X⁴ + ...

một lần nữa, sử dụng mở rộng chuỗi sức mạnh (được thực hiện với Wolfram Alpha ). Điều này thể hiện một thực tế không rõ ràng (với tôi) rằng chỉ có một cây nhị phân có 1 phần tử, 2 cây nhị phân có hai phần tử (phần tử thứ hai có thể ở bên trái hoặc nhánh bên phải), 5 cây nhị phân có ba phần tử, v.v. .

Vì vậy, câu hỏi của tôi là - tôi đang làm gì ở đây? Các hoạt động này có vẻ không chính đáng (chính xác thì căn bậc hai của kiểu dữ liệu đại số là gì?) Nhưng chúng dẫn đến kết quả hợp lý. Liệu thương số của hai loại dữ liệu đại số có bất kỳ ý nghĩa nào trong khoa học máy tính, hay nó chỉ là mánh khóe công chứng?

Và, có lẽ thú vị hơn, liệu có thể mở rộng những ý tưởng này? Có một lý thuyết về đại số của các loại cho phép, ví dụ, các hàm tùy ý trên các loại, hoặc các loại yêu cầu một biểu diễn chuỗi lũy thừa? Nếu bạn có thể định nghĩa một lớp các hàm, thì thành phần của các hàm có ý nghĩa gì không?


19
Bạn có thể thấy điều này thú vị / có liên quan: blog.lab49.com/archives/3011
shang

4
Không nếu nó lưu trữ dữ liệu trong mỗi nút. Nó có vẻ như Branch x (Branch y Nil Nil) Nilhoặc nó trông giống như Branch x Nil (Branch y Nil Nil).
Chris Taylor

4
@nlucaroni: dưới cùng là một giá trị, không phải là một loại. Một loại không thực sự sẽ không có giá trị của loại đó, điều này không thể có trong Haskell trừ khi bạn bỏ qua các đáy. Nếu bạn tính đến các giá trị dưới cùng, thì các loại chỉ chứa các đáy sẽ trở thành loại đơn vị ... không hữu ích trong hầu hết thời gian và cũng có rất nhiều thứ khác bị phá vỡ.
CA McCann

3
Tôi đồng ý đó là thông lệ Haskell thông thường, nó vẫn ngớ ngẩn. Cụ thể, điều đó có nghĩa là chúng tôi sử dụng "đáy" một cách khác nhau sau đó họ làm theo logic và loại lý thuyết mà điều này có hại cho tôi. Nhìn giống nhau từ mã thuần không làm cho chúng giống nhau: "Xử lý đội lúng túng" cho thấy rõ rằng ngữ nghĩa của Haskell có một loạt các "giá trị xấu" lặp đi lặp lại và ném ngoại lệ rõ ràng không giống nhau . Thay thế cái này cho cái kia không phải là lý luận tương đương hợp lệ. Haskell có một vốn từ vựng để mô tả các giá trị xấu undefined, throwvv Chúng ta nên sử dụng nó.
Philip JF

17
Tâm trí của tôi đã bị thổi bay bởi câu hỏi này
TheIronKnuckle

Câu trả lời:


138

Tuyên bố miễn trừ trách nhiệm: Rất nhiều điều này không thực sự hoạt động hoàn toàn đúng khi bạn tính đến, vì vậy tôi sẽ coi nhẹ việc đó vì mục đích đơn giản.

Một vài điểm ban đầu:

  • Lưu ý rằng "công đoàn" có lẽ không phải là hạn tốt nhất cho A + B ở đây - đó là đặc biệt một rời nhau đoàn của hai loại, bởi vì hai bên được phân biệt ngay cả khi loại của họ đều giống nhau. Đối với những gì nó có giá trị, thuật ngữ phổ biến hơn chỉ đơn giản là "loại tổng".

  • Các loại đơn là, hiệu quả, tất cả các loại đơn vị. Họ hành xử giống hệt nhau dưới các thao tác đại số và quan trọng hơn, lượng thông tin hiện tại vẫn được bảo tồn.

  • Bạn có thể muốn một loại không là tốt. Haskell cung cấp rằng như Void. Không có giá trị nào có loại bằng 0, giống như có một giá trị có loại là một.

Vẫn còn một hoạt động chính bị thiếu ở đây nhưng tôi sẽ quay lại ngay.

Như bạn có thể nhận thấy, Haskell có xu hướng mượn các khái niệm từ Lý thuyết Danh mục và tất cả những điều trên có cách giải thích rất đơn giản như sau:

  • Cho các đối tượng A và B trong Hask , sản phẩm A × B của chúng là loại duy nhất (tối đa đẳng cấu) cho phép hai hình chiếu fst : A × B → A và snd : A × B → B, trong đó có bất kỳ loại C và hàm f : C → A, g : C → B bạn có thể xác định ghép f &&& g : C → A × B sao cho fst ∘ (f &&& g) = f và tương tự cho g . Tham số đảm bảo các thuộc tính phổ quát tự động và sự lựa chọn tên kém tinh tế của tôi sẽ cho bạn ý tưởng. Nhân tiện, (&&&)toán tử được định nghĩa Control.Arrow.

  • Nguyên tắc kép ở trên là sao chép A + B với các mũi tiêm inl : A → A + B và inr : B → A + B, trong đó cho bất kỳ loại C và chức năng f : A → C, g : B → C, bạn có thể định nghĩa sự đối phó f ||| g : A + B → C sao cho tương đương rõ ràng giữ. Một lần nữa, tham số đảm bảo hầu hết các phần khó khăn tự động. Trong trường hợp này, tiêm tiêu chuẩn là đơn giản LeftRightcopairing là chức năng either.

Nhiều thuộc tính của các loại sản phẩm và tổng có thể được bắt nguồn từ ở trên. Lưu ý rằng bất kỳ loại singleton nào cũng là đối tượng đầu cuối của Hask và bất kỳ loại trống nào cũng là đối tượng ban đầu.

Quay trở lại hoạt động mất tích đã nói ở trên, trong danh mục đóng cartesian, bạn có các đối tượng theo cấp số nhân tương ứng với các mũi tên của danh mục. Mũi tên của chúng ta là các hàm, các đối tượng của chúng ta là các loại có loại *và loại A -> Bthực sự hoạt động như B A trong bối cảnh thao tác đại số của các loại. Nếu nó không rõ ràng tại sao điều này nên giữ, hãy xem xét các loại Bool -> A. Chỉ với hai đầu vào có thể, một hàm của loại đó là đẳng cấu với hai giá trị của loại A, tức là (A, A). Đối với Maybe Bool -> Achúng tôi có ba đầu vào có thể, và như vậy. Ngoài ra, quan sát rằng nếu chúng ta viết lại định nghĩa copairing ở trên để sử dụng ký hiệu đại số, chúng ta sẽ nhận được C A × C B = CA + B .

Về lý do tại sao tất cả điều này có ý nghĩa - và đặc biệt tại sao việc sử dụng mở rộng chuỗi năng lượng của bạn là hợp lý - lưu ý rằng phần lớn ở trên đề cập đến "cư dân" của một loại (nghĩa là các giá trị riêng biệt có loại đó) theo thứ tự để chứng minh hành vi đại số. Để làm cho quan điểm đó rõ ràng:

  • Loại sản phẩm (A, B)đại diện cho một giá trị mỗi từ AB, được thực hiện độc lập. Vì vậy, đối với bất kỳ giá trị cố định nào a :: A, có một giá trị loại (A, B)cho mỗi cư dân B. Tất nhiên đây là sản phẩm của cartesian, và số lượng cư dân của loại sản phẩm là sản phẩm của số lượng cư dân của các yếu tố.

  • Loại tổng Either A Bđại diện cho một giá trị từ một Ahoặc B, với các nhánh trái và phải được phân biệt. Như đã đề cập trước đó, đây là một liên minh rời rạc và số lượng cư dân của loại tổng là tổng của số lượng cư dân của các triệu hồi.

  • Kiểu hàm mũ B -> Abiểu thị ánh xạ từ giá trị của kiểu này Bsang giá trị của kiểu A. Đối với bất kỳ đối số cố định b :: B, bất kỳ giá trị nào Acó thể được gán cho nó; một giá trị kiểu B -> Anhặt một bản đồ như vậy cho mỗi đầu vào, đó là tương đương với một sản phẩm càng nhiều bản sao của Anhư Bcó cư dân, vì thế mà lũy thừa.

Mặc dù ban đầu nó rất hấp dẫn khi coi các loại là tập hợp, nhưng điều đó thực sự không hoạt động tốt trong bối cảnh này - chúng tôi phân biệt liên minh thay vì liên hiệp tiêu chuẩn của tập hợp, không có giải thích rõ ràng về giao lộ hoặc nhiều hoạt động tập hợp khác, và chúng tôi thường không quan tâm đến việc đặt thành viên (để lại cho trình kiểm tra loại).

Mặt khác, các công trình trên dành nhiều thời gian để nói về việc đếm cư dân, và liệt kê các giá trị có thể có của một loại là một khái niệm hữu ích ở đây. Điều đó nhanh chóng dẫn chúng ta đến tổ hợp số lượng lớn và nếu bạn tham khảo bài viết Wikipedia được liên kết, bạn sẽ thấy rằng một trong những điều đầu tiên nó làm là "cặp" và "hiệp hội" theo nghĩa chính xác giống như các loại sản phẩm và tổng hợp theo cách tạo các hàm , sau đó thực hiện tương tự cho "chuỗi" giống hệt với danh sách của Haskell bằng cách sử dụng chính xác cùng một kỹ thuật bạn đã làm.


Chỉnh sửa: Ồ, và đây là một phần thưởng nhanh chóng mà tôi nghĩ là minh chứng cho điểm nổi bật. Bạn đã đề cập trong một nhận xét rằng đối với một loại cây T = 1 + T^2bạn có thể lấy được danh tính T^6 = 1, điều này rõ ràng là sai. Tuy nhiên, T^7 = T giữ được không , và một phần tử giữa cây và bảy tấc cây có thể được xây dựng trực tiếp, xem "Bảy cây trong một" của Andreas Blass .

Chỉnh sửa × 2: Về chủ đề xây dựng "đạo hàm của một loại" được đề cập trong các câu trả lời khác, bạn cũng có thể thưởng thức bài viết này từ cùng một tác giả xây dựng ý tưởng hơn nữa, bao gồm các khái niệm về phân chia và các thông báo thú vị khác.


3
Đây là một lời giải thích tuyệt vời, đặc biệt là một điểm xuất phát trong những thứ như nghiêm
ngặt.org / diff.pdf

26
@acreastzer: Cảm ơn! :] Và vâng, đó là một bài báo tuyệt vời phát triển những ý tưởng này. Bạn biết đấy, tôi nghĩ rằng ít nhất 5% tổng danh tiếng của tôi về SO có thể được quy cho là "giúp mọi người hiểu một trong những bài báo của Conor McBride" ...
CA McCann

45

Cây nhị phân được xác định bởi phương trình T=1+XT^2trong nửa loại. Bằng cách xây dựng, T=(1-sqrt(1-4X))/(2X)được xác định bởi cùng một phương trình trong việc tạo ra các số phức. Vì vậy, khi chúng ta giải cùng một phương trình trong cùng một lớp cấu trúc đại số, thực sự không có gì đáng ngạc nhiên khi chúng ta thấy một số điểm tương đồng.

Điều đáng chú ý là khi chúng ta suy luận về đa thức trong việc tạo ra các số phức, chúng ta thường sử dụng thực tế là các số phức tạo thành một vòng hoặc thậm chí là một trường để chúng ta thấy mình sử dụng các phép toán như phép trừ không áp dụng cho bán dẫn. Nhưng chúng ta thường có thể loại bỏ các phép trừ khỏi các đối số của mình nếu chúng ta có một quy tắc cho phép chúng ta hủy bỏ từ cả hai phía của một phương trình. Đây là loại điều được chứng minh bởi Fiore và Leinster cho thấy nhiều tranh luận về nhẫn có thể được chuyển sang bán kết.

Điều này có nghĩa là rất nhiều kiến ​​thức toán học của bạn về các vòng có thể được chuyển một cách đáng tin cậy sang các loại. Kết quả là, một số đối số liên quan đến số phức hoặc chuỗi lũy thừa (trong vòng của chuỗi quyền lực chính thức) có thể chuyển sang các loại theo một cách hoàn toàn nghiêm ngặt.

Tuy nhiên có nhiều câu chuyện hơn thế này. Đó là một điều để chứng minh hai loại bằng nhau (giả sử) bằng cách hiển thị hai chuỗi lũy thừa bằng nhau. Nhưng bạn cũng có thể suy luận thông tin về các loại bằng cách kiểm tra các điều khoản trong chuỗi quyền lực. Tôi không chắc chắn những gì tuyên bố chính thức ở đây nên được. (Tôi đề nghị giấy của Brent Yorge về các loài tổ hợp cho một số công việc có liên quan chặt chẽ nhưng các loài không giống như các loại.)

Những gì tôi thấy hoàn toàn thổi tâm trí là những gì bạn đã khám phá có thể được mở rộng để tính toán. Các định lý về tính toán có thể được chuyển qua các loại hình. Trong thực tế, thậm chí các lập luận về sự khác biệt hữu hạn có thể được chuyển qua và bạn thấy rằng các định lý cổ điển từ phân tích số có các diễn giải trong lý thuyết loại.

Chúc vui vẻ!


Sự khác biệt / công cụ bối cảnh một lỗ này là khá mát mẻ. Hãy xem tôi có nói thẳng điều này không. Một cặp, với đại diện đại số P = X^2, có đạo hàm dP = X + X, Eitherbối cảnh một lỗ của cặp cũng vậy. Điều đó thật tuyệt. Chúng tôi có thể 'hòa nhập' Eitherđể có được một cặp quá. Nhưng nếu chúng ta cố gắng 'tích hợp' Maybe(với loại M = 1 + X) thì chúng ta cần phải có \int M = X + X^2 / 2thứ không hợp lý (loại nào là một nửa?) Điều này có nghĩa đó Maybekhông phải là bối cảnh một lỗ của bất kỳ loại nào khác phải không?
Chris Taylor

6
@ChrisTaylor: Bối cảnh một lỗ lưu giữ thông tin về vị trí bên trong các sản phẩm, nghĩa là, (A,A)với một lỗ hổng trong đó là một Avà một chút cho bạn biết lỗ nào nằm ở phía nào. Một Amình không có lỗ hổng riêng biệt để điền vào, đó là lý do tại sao bạn không thể "tích hợp" nó. Tất nhiên, loại thông tin còn thiếu trong trường hợp này là 2.
CA McCann

Tôi đã viết về ý nghĩa của các loại như X^2/2 blog.sigfpe.com/2007/09/type-of-distinc-pairs.html
sigfpe

@ user207442, chẳng phải bạn cũng đã làm gì đó về sự khuất phục giữa một cây và bảy cây sao? Tôi đã liên kết với một bài báo về điều đó trong câu trả lời của tôi nhưng tôi có thể thề rằng tôi nhớ lần đầu tiên đọc về nó trên blog của bạn.
CA McCann

1
@ChrisTaylor On hữu hạn (thực sự "chia") khác biệt có này: strictlypositive.org/CJ.pdf Nhưng tại thời điểm đó Conor đã không nhận ra rằng ông đã mô tả sự khác biệt. Tôi đã viết điều này mặc dù có thể rất khó để theo dõi: blog.sigfpe.com/2010/08/ Nhật Tôi sẽ viết một bài báo nhưng tôi không giỏi lắm trong việc hoàn thiện chúng.
sigfpe

22

Dường như tất cả những gì bạn đang làm là mở rộng mối quan hệ tái phát.

L = 1 + X  L
L = 1 + X  (1 + X  (1 + X  (1 + X  ...)))
  = 1 + X + X^2 + X^3 + X^4 ...

T = 1 + X  T^2
L = 1 + X  (1 + X  (1 + X  (1 + X  ...^2)^2)^2)^2
  = 1 + X + 2  X^2 + 5  X^3 + 14  X^4 + ...

Và vì các quy tắc cho các hoạt động trên các loại hoạt động giống như quy tắc cho các hoạt động số học, bạn có thể sử dụng các phương tiện đại số để giúp bạn tìm ra cách mở rộng mối quan hệ lặp lại (vì nó không rõ ràng).


1
"Vì các quy tắc cho các hoạt động trên các loại hoạt động giống như các quy tắc cho các hoạt động số học ..." - mặc dù vậy, chúng không. Không có khái niệm về các loại trừ, hãy để một mình phân chia và căn bậc hai. Vì vậy, tôi đoán câu hỏi của tôi là: khi nào bạn có thể đi từ một thao tác đại số giả sử Xlà một yếu tố của các số thực thành một tuyên bố đúng về các loại, và hơn nữa, trong đó sự tương ứng (hệ số của nthuật ngữ bậc) <=> (số các loại nyếu tố nắm giữ ) đến từ đâu?
Chris Taylor

1
Ví dụ: từ biểu thức cho Cây ( T = 1 + T^2) tôi có thể rút ra T^6 = 1(nghĩa là các giải pháp x^2 - x + 1 = 0là gốc thứ sáu của sự thống nhất) nhưng rõ ràng không đúng khi một loại sản phẩm bao gồm sáu cây nhị phân tương đương với đơn vị ().
Chris Taylor

3
@ChrisTaylor, nhưng có cái gì đó đang xảy ra ở đó, vì có một đẳng cấu giữa T^7T. xem arxiv.org/abs/math/9405205
luqui

7
@ChrisTaylor, đây là một cái gì đó để suy nghĩ. Khi bạn thêm các phép toán đại số mới, bạn hy vọng không phá vỡ các thuộc tính của các phép toán hiện có. Nếu bạn có thể đi đến cùng một câu trả lời theo hai cách khác nhau, họ nên đồng ý. Vì vậy, cung cấp có bất kỳ đại diện ở tất cả cho L = 1 + X * L, nó có tốt hơn là người tương tự mà bạn nhận được khi bạn mở rộng hàng loạt, bởi tính nhất quán. Nếu không, bạn có thể chạy kết quả ngược lại để nhận được một cái gì đó sai về thực tế.
luqui

2
@ChrisTaylor Thực sự có một khái niệm phân chia các loại, tìm kiếm "Loại đơn vị" để biết thêm thông tin. Cho dù nó tương ứng tốt với phân chia đa thức, tôi không biết. Nó xảy ra khá phi thực tế, imho, nhưng nó ở ngoài đó.
Doug McClean

18

Tôi không có câu trả lời hoàn chỉnh, nhưng những thao tác này có xu hướng 'chỉ hoạt động'. Một bài báo có liên quan có thể là Đối tượng của Danh mục dưới dạng Số phức của Fiore và Leinster - Tôi tình cờ thấy bài đó khi đọc blog của sigfpe về một chủ đề liên quan ; phần còn lại của blog đó là một mỏ vàng cho những ý tưởng tương tự và đáng để kiểm tra!

Nhân tiện, bạn cũng có thể phân biệt các kiểu dữ liệu - điều đó sẽ giúp bạn có được Zipper phù hợp cho kiểu dữ liệu!


12
Thủ thuật Zipper thật tuyệt vời. Tôi ước tôi hiểu nó.
spraff

Bạn cũng có thể tạo các khóa kéo trong Lược đồ bằng cách sử dụng các liên tục được phân tách, cho phép bạn lấy chúng một cách tổng quát.
Jon Purdy

10

Đại số của các quá trình giao tiếp (ACP) liên quan đến các loại biểu thức tương tự cho các quy trình. Nó cung cấp cộng và nhân như các toán tử cho sự lựa chọn và trình tự, với các yếu tố trung tính liên quan. Dựa trên những điều này có các toán tử cho các cấu trúc khác, chẳng hạn như song song và gián đoạn. Xem http://en.wikipedia.org/wiki/Algebra_of_Cransicating_Processes . Ngoài ra còn có một bài báo trực tuyến có tên "Lịch sử tóm tắt về đại số quá trình".

Tôi đang làm việc để mở rộng ngôn ngữ lập trình với ACP. Tháng 4 năm ngoái tôi đã trình bày một bài nghiên cứu tại Scala Days 2012, có sẵn tại http://code.google.com.vn/p/subcript/

Tại hội nghị, tôi đã trình diễn một trình gỡ lỗi chạy một đặc tả đệ quy song song của túi:

Túi = A; (Túi & a)

trong đó A và một giá đỡ cho các hành động đầu vào và đầu ra; dấu chấm phẩy và ký hiệu là viết tắt của trình tự và song song. Xem video tại SkillMatter, có thể truy cập từ liên kết trước.

Một đặc điểm kỹ thuật túi tương đương với

L = 1 + X • L

sẽ là

B = 1 + X & B

ACP định nghĩa song song về mặt lựa chọn và trình tự sử dụng các tiên đề; xem bài viết Wikipedia. Tôi tự hỏi những gì tương tự túi sẽ được cho

L = 1 / (1-X)

Lập trình kiểu ACP thuận tiện cho trình phân tích cú pháp văn bản và bộ điều khiển GUI. Thông số kỹ thuật như

searchCommand = đã nhấp (searchButton) + key (Enter)

hủyCommand = đã nhấp (hủy nút) + phím (Thoát)

có thể được viết ra chính xác hơn bằng cách làm cho hai tinh chỉnh "nhấp chuột" và "khóa" ẩn (giống như những gì Scala cho phép với các chức năng). Do đó chúng ta có thể viết:

searchCommand = searchButton + Enter

hủyCommand = hủyButton + Escape

Phía bên tay phải bây giờ chứa các toán hạng là dữ liệu, thay vì các quy trình. Ở cấp độ này, không cần thiết phải biết những sàng lọc ngầm nào sẽ biến các toán hạng này thành các quy trình; họ không nhất thiết phải tinh chỉnh thành các hành động đầu vào; hành động đầu ra cũng sẽ được áp dụng, ví dụ như trong đặc điểm kỹ thuật của robot thử nghiệm.

Các quy trình có được dữ liệu theo cách này như là bạn đồng hành; do đó tôi đồng xu với thuật ngữ "đại số mục".


6

Sê-ri tính toán và Maclaurin với các loại

Đây là một bổ sung nhỏ khác - một cái nhìn sâu sắc kết hợp về lý do tại sao các hệ số trong mở rộng chuỗi nên 'hoạt động', đặc biệt tập trung vào chuỗi có thể được lấy bằng cách sử dụng phương pháp Taylor-Maclaurin từ phép tính. NB: mở rộng chuỗi ví dụ bạn đưa ra của loại danh sách bị thao túng là một chuỗi Maclaurin.

Vì các câu trả lời và nhận xét khác liên quan đến hành vi của các biểu thức đại số (tổng, sản phẩm và số mũ), câu trả lời này sẽ phù hợp với chi tiết đó và tập trung vào loại 'tính toán'.

Bạn có thể nhận thấy dấu phẩy đảo ngược làm một số nặng trong câu trả lời này. Có hai lý do:

  • chúng tôi đang nỗ lực đưa ra các diễn giải từ một miền cho các thực thể từ một thực thể khác và có vẻ phù hợp để phân định các khái niệm nước ngoài như vậy theo cách này.
  • một số khái niệm sẽ có thể được chính thức hóa chặt chẽ hơn, nhưng hình dạng và ý tưởng có vẻ quan trọng hơn (và tốn ít không gian để viết) hơn các chi tiết.

Định nghĩa của loạt Maclaurin

Chuỗi Maclaurin của một hàm f : ℝ → ℝđược định nghĩa là

f(0) + f'(0)X + (1/2)f''(0)X² + ... + (1/n!)f⁽ⁿ⁾(0)Xⁿ + ...

trong đó f⁽ⁿ⁾có nghĩa là nđạo hàm thứ của f.

Để có thể hiểu được chuỗi Maclaurin như được giải thích với các loại, chúng ta cần hiểu làm thế nào chúng ta có thể diễn giải ba điều trong ngữ cảnh loại:

  • một đạo hàm (có thể là nhiều)
  • áp dụng một chức năng cho 0
  • điều khoản như (1/n!)

và nó chỉ ra rằng các khái niệm từ phân tích có các đối tác phù hợp trong thế giới loại.

Ý tôi là 'đối tác phù hợp' nghĩa là gì? Nó nên có hương vị của một đẳng cấu - nếu chúng ta có thể bảo tồn sự thật theo cả hai hướng, các sự kiện có thể dẫn xuất trong một bối cảnh có thể được chuyển sang bối cảnh khác.

Tính toán với các loại

Vì vậy, đạo hàm của một biểu thức loại có nghĩa là gì? Nó chỉ ra rằng đối với một lớp biểu thức và hàm functor lớn và hoạt động tốt ('khác biệt'), có một hoạt động tự nhiên có hành vi tương tự đủ để trở thành một cách giải thích phù hợp!

Để làm hỏng đường đột, hoạt động tương tự như sự khác biệt là tạo ra 'bối cảnh một lỗ'. Đây là một nơi tuyệt vời để mở rộng về điểm đặc biệt này hơn nữa nhưng khái niệm cơ bản về bối cảnh một lỗ ( da/dx) là nó thể hiện kết quả của việc trích xuất một tiểu mục duy nhất của một loại cụ thể ( x) từ một thuật ngữ (loại a), bảo tồn tất cả các thông tin khác, bao gồm cả thông tin cần thiết để xác định vị trí ban đầu của phụ đề. Ví dụ: một cách để thể hiện bối cảnh một lỗ cho danh sách là hai danh sách: một cho các mục xuất hiện trước mục được trích xuất và một cho các mục xuất hiện sau.

Động lực để xác định hoạt động này với sự khác biệt đến từ các quan sát sau đây. Chúng tôi viết da/dxcó nghĩa là loại bối cảnh một lỗ cho loại acó lỗ loại x.

d1/dx = 0
dx/dx = 1
d(a + b)/dx = da/dx + db/dx
d(a × b)/dx = a × db/dx + b × da/dx
d(g(f(x))/dx = d(g(y))/dy[f(x)/a] × df(x)/dx

Ở đây, 10đại diện cho các loại với chính xác một và không có cư dân chính xác, tương ứng, +×đại diện cho các loại tổng và sản phẩm như bình thường. fgđược sử dụng để biểu diễn các hàm kiểu, hoặc các định dạng biểu thức kiểu, và [f(x)/a]có nghĩa là hoạt động thay thế f(x)cho mọi atrong biểu thức trước.

Điều này có thể được viết theo kiểu không có điểm, viết f'có nghĩa là hàm phái sinh của hàm loại f, do đó:

(x ↦ 1)' = x ↦ 0
(x ↦ x)' = x ↦ 1
(f + g)' = f' + g'
(f × g)' = f × g' + g × f'
(g ∘ f)' = (g' ∘ f) × f'

có thể thích hợp hơn

NB các đẳng thức có thể được thực hiện nghiêm ngặt và chính xác nếu chúng ta định nghĩa các đạo hàm bằng cách sử dụng các lớp đẳng cấu của các kiểu và hàm tử.

Bây giờ, chúng tôi đặc biệt lưu ý rằng các quy tắc tính toán liên quan đến các phép toán đại số của phép cộng, phép nhân và thành phần (thường được gọi là quy tắc Sum, Sản phẩm và Chuỗi) được phản ánh chính xác bằng hoạt động 'tạo lỗ'. Hơn nữa, các trường hợp cơ bản của 'tạo lỗ' trong một biểu thức không đổi hoặc xchính thuật ngữ này cũng hoạt động như sự khác biệt, do đó, bằng cách cảm ứng, chúng ta có hành vi giống như sự khác biệt cho tất cả các biểu thức đại số.

Bây giờ chúng ta có thể giải thích sự khác biệt, n"đạo hàm" của một biểu thức kiểu dⁿe/dxⁿlà gì? Đó là một loại đại diện cho nbối cảnh tại chỗ: các thuật ngữ mà khi được 'điền' với ncác điều khoản của loại xmang lại một e. Có một quan sát quan trọng khác liên quan đến ' (1/n!)' đến sau.

Phần bất biến của functor kiểu: áp dụng hàm cho 0

Chúng ta đã có một cách giải thích 0trong thế giới loại: một loại trống không có thành viên. Điều đó có nghĩa là gì, từ quan điểm tổ hợp, để áp dụng một hàm loại cho nó? Nói một cách cụ thể hơn, giả sử flà một hàm kiểu, f(0)trông như thế nào? Chà, chúng tôi chắc chắn không có quyền truy cập vào bất kỳ loại nào 0, do đó, bất kỳ công trình f(x)nào yêu cầu xkhông có sẵn. Những gì còn lại là những thuật ngữ có thể truy cập được khi vắng mặt, mà chúng ta có thể gọi là phần 'bất biến' hoặc 'hằng số' của loại.

Đối với một ví dụ rõ ràng, lấy Maybefunctor, có thể được biểu diễn đại số là x ↦ 1 + x. Khi chúng tôi áp dụng điều này cho 0, chúng tôi nhận được 1 + 0- nó giống như 1: giá trị duy nhất có thể là Nonegiá trị. Đối với một danh sách, tương tự, chúng tôi chỉ nhận được thuật ngữ tương ứng với danh sách trống.

Khi chúng tôi đưa nó trở lại và giải thích kiểu f(0)như một số nó có thể được coi như là đếm có bao nhiêu về chủng loại f(x)(đối với bất kỳ x) có thể thu được mà không cần truy cập vào một x: đó là, số lượng 'trắng như' thuật ngữ .

Đặt nó lại với nhau: giải thích hoàn chỉnh một loạt Maclaurin

Tôi sợ rằng tôi không thể nghĩ ra một cách giải thích trực tiếp thích hợp (1/n!)như một kiểu.

Nếu chúng ta xem xét, tuy nhiên, loại f⁽ⁿ⁾(0)trong bối cảnh trên, chúng ta thấy rằng nó có thể được hiểu là các loại nbối cảnh -place với nhiệm kỳ loại f(x)không đã chứa một x - có nghĩa là, khi chúng ta 'Tích hợp' họ nlần , thuật ngữ kết quả có chính xác n x s, không hơn, không kém. Sau đó, việc giải thích loại f⁽ⁿ⁾(0)dưới dạng một số (như trong các hệ số của chuỗi Maclaurin f) chỉ đơn giản là đếm xem có bao nhiêu nbối cảnh trống như vậy . Chúng tôi đang ở gần đó!

Nhưng (1/n!)cuối cùng ở đâu? Kiểm tra quá trình 'phân biệt' cho chúng ta thấy rằng, khi được áp dụng nhiều lần, nó sẽ giữ được 'thứ tự' trong đó các phần tử con được trích xuất. Ví dụ, hãy xem xét thuật ngữ (x₀, x₁)của loại x × xvà hoạt động 'tạo lỗ' trong đó hai lần. Chúng tôi nhận được cả hai chuỗi

(x₀, x₁)  ↝  (_₀, x₁)  ↝  (_₀, _₁)
(x₀, x₁)  ↝  (x₀, _₀)  ↝  (_₁, _₀)
(where _ represents a 'hole')

mặc dù cả hai đều xuất phát từ cùng một thuật ngữ, bởi vì có nhiều 2! = 2cách để lấy hai yếu tố từ hai, giữ gìn trật tự. Nói chung, có nhiềun! cách để lấy ncác yếu tố từ n. Vì vậy, để có được số lượng cấu hình của loại functor có ncác phần tử, chúng ta phải đếm loại f⁽ⁿ⁾(0)và chia cho n!, chính xác như trong các hệ số của chuỗi Maclaurin.

Vì vậy, phân chia bằng cách n!hóa ra có thể hiểu được chỉ đơn giản là chính nó.

Suy nghĩ cuối cùng: định nghĩa và phân tích 'đệ quy'

Đầu tiên, một số quan sát:

  • nếu một hàm f: → có đạo hàm thì đạo hàm này là duy nhất
  • tương tự, nếu một hàm f: ℝ → là giải tích, nó có chính xác một chuỗi đa thức tương ứng

Vì chúng ta có quy tắc chuỗi, chúng ta có thể sử dụng sự khác biệt ngầm định , nếu chúng ta chính thức hóa các dẫn xuất loại như các lớp đẳng cấu. Nhưng sự khác biệt ngầm không yêu cầu bất kỳ thao tác ngoài hành tinh nào như trừ hoặc chia! Vì vậy, chúng ta có thể sử dụng nó để phân tích các định nghĩa kiểu đệ quy. Lấy ví dụ về danh sách của bạn, chúng tôi có

L(X) ≅ 1 + X × L(X)
L'(X) = X × L'(X) + L(X)

và sau đó chúng ta có thể đánh giá

L'(0) = L(0) = 1

để có được hệ số trong chuỗi Maclaurin.

Nhưng vì chúng tôi tin tưởng rằng các biểu thức này thực sự hoàn toàn 'khác biệt', nếu chỉ là ngầm và vì chúng tôi có sự tương ứng với các hàm ℝ →, trong đó các đạo hàm chắc chắn là duy nhất, chúng tôi có thể yên tâm rằng ngay cả khi chúng tôi có được các giá trị bằng cách sử dụng ' hoạt động bất hợp pháp, kết quả là hợp lệ.

Bây giờ, tương tự, để sử dụng quan sát thứ hai, do sự tương ứng (có phải là đồng cấu không?) Với các hàm ℝ →, chúng tôi biết rằng, với điều kiện chúng tôi hài lòng rằng một hàm chuỗi Maclaurin, nếu chúng tôi có thể tìm thấy bất kỳ chuỗi nào tại tất cả , các nguyên tắc được nêu ở trên có thể được áp dụng để làm cho nó nghiêm ngặt.

Đối với câu hỏi của bạn về thành phần của các hàm, tôi cho rằng quy tắc chuỗi cung cấp một câu trả lời một phần.

Tôi không chắc có bao nhiêu ADT kiểu Haskell này áp dụng cho, nhưng tôi nghi ngờ nó là nhiều nếu không phải là tất cả. Tôi đã phát hiện ra một bằng chứng thực sự tuyệt vời về thực tế này, nhưng biên độ này quá nhỏ để chứa nó ...

Bây giờ, chắc chắn đây chỉ là một cách để tìm ra những gì đang diễn ra ở đây và có lẽ có nhiều cách khác.

Tóm tắt: TL; DR

  • gõ 'phân biệt' tương ứng với ' tạo lỗ '.
  • áp dụng một functor để cung cấp cho 0chúng tôi các thuật ngữ 'giống như trống rỗng' cho functor đó.
  • Do đó, chuỗi sức mạnh Maclaurin (phần nào) tương ứng chặt chẽ với việc liệt kê số lượng thành viên của một loại functor với một số yếu tố nhất định.
  • sự khác biệt ngầm làm cho điều này kín nước hơn.
  • tính độc đáo của các công cụ phái sinh và tính độc đáo của chuỗi lũy thừa có nghĩa là chúng ta có thể làm mờ các chi tiết và nó hoạt động.

6

Lý thuyết loại phụ thuộc và các hàm loại 'tùy ý'

Câu trả lời đầu tiên của tôi cho câu hỏi này là cao về các khái niệm và thấp về chi tiết và được phản ánh về câu hỏi phụ, 'chuyện gì đang xảy ra?'; câu trả lời này sẽ giống nhau nhưng tập trung vào truy vấn con, 'chúng ta có thể có các hàm loại tùy ý không?'.

Một phần mở rộng cho các phép toán đại số của tổng và sản phẩm được gọi là 'toán tử lớn', đại diện cho tổng và tích của một chuỗi (hay nói chung hơn là tổng và tích của hàm trên một miền) thường được viết ΣΠtương ứng. Xem ký hiệu Sigma .

Vậy tổng

a + aX + aX² + ...

có thể được viết

Σ[i  ℕ]aX

nơi amột số chuỗi các số thực, ví dụ. Sản phẩm sẽ được đại diện tương tự với Πthay vì Σ.

Khi bạn nhìn từ xa, loại biểu thức này trông rất giống chức năng 'tùy ý' trong X; tất nhiên chúng tôi giới hạn trong chuỗi có thể biểu thị và các chức năng phân tích liên quan của chúng. Đây có phải là một ứng cử viên cho một đại diện trong một lý thuyết loại? Chắc chắn rồi!

Lớp lý thuyết loại có biểu diễn ngay lập tức của các biểu thức này là lớp lý thuyết loại 'phụ thuộc': lý thuyết với loại phụ thuộc. Đương nhiên, chúng ta có các thuật ngữ phụ thuộc vào các thuật ngữ và trong các ngôn ngữ như Haskell với các hàm loại và định lượng kiểu, thuật ngữ và loại tùy thuộc vào loại. Trong một cài đặt phụ thuộc, chúng tôi cũng có các loại tùy thuộc vào các điều khoản. Haskell không phải là một ngôn ngữ được gõ phụ thuộc, mặc dù nhiều tính năng của các loại phụ thuộc có thể được mô phỏng bằng cách tra tấn ngôn ngữ một chút .

Curry-Howard và các loại phụ thuộc

'Đồng phân Curry-Howard bắt đầu cuộc sống như một quan sát rằng các thuật ngữ và quy tắc đánh giá loại của phép tính lambda được gõ đơn giản tương ứng chính xác với suy luận tự nhiên (theo công thức của Gentzen) áp dụng cho logic mệnh đề trực giác, với các kiểu thay thế cho các mệnh đề và các điều khoản thay thế bằng chứng, mặc dù cả hai được phát minh / phát hiện độc lập. Kể từ đó, nó là một nguồn cảm hứng lớn cho các nhà lý thuyết loại. Một trong những điều rõ ràng nhất để xem xét là liệu, và làm thế nào, sự tương ứng này cho logic mệnh đề có thể được mở rộng để logic vị ngữ hoặc thứ tự cao hơn. Các lý thuyết loại phụ thuộc ban đầu nảy sinh từ con đường thăm dò này.

Để biết giới thiệu về đẳng cấu Curry-Howard cho phép tính lambda được gõ đơn giản, xem tại đây . Ví dụ, nếu chúng ta muốn chứng minh, A ∧ Bchúng ta phải chứng minh Avà chứng minh B; một bằng chứng kết hợp chỉ đơn giản là một cặp bằng chứng: một cho mỗi kết luận.

Trong khấu trừ tự nhiên:

Γ  A    Γ  B
Γ  A  B

và trong phép tính lambda được gõ đơn giản:

Γ  a : A    Γ  b : B
Γ  (a, b) : A × B

Tương ứng tương tự tồn tại cho các loại và tổng, và các loại chức năng, và các quy tắc loại bỏ khác nhau.

Một đề xuất không thể chứng minh (sai trực giác) tương ứng với một loại không có người ở.

Với sự tương tự của các loại như các đề xuất logic trong tâm trí, chúng ta có thể bắt đầu xem xét cách mô hình các vị từ trong thế giới loại. Có nhiều cách mà điều này đã được chính thức hóa (xem phần giới thiệu về Lý thuyết loại trực giác của Martin-Löf cho một tiêu chuẩn được sử dụng rộng rãi) nhưng cách tiếp cận trừu tượng thường quan sát rằng một vị ngữ giống như một mệnh đề với các biến thuật ngữ tự do, hoặc, thay vào đó, một hàm lấy các điều khoản cho các mệnh đề. Nếu chúng ta cho phép các biểu thức kiểu chứa các thuật ngữ, thì một cách xử lý theo kiểu tính toán lambda ngay lập tức thể hiện chính nó như một khả năng!

Chỉ xem xét các bằng chứng mang tính xây dựng, những gì tạo thành một bằng chứng về ∀x ∈ X.P(x)? Chúng ta có thể nghĩ về nó như là một hàm chứng minh, lấy các số hạng ( x) để chứng minh các mệnh đề tương ứng của chúng ( P(x)). Vì vậy, các thành viên (bằng chứng) của các loại (đề xuất) ∀x : X.P(x)là 'chức năng phụ thuộc', mà đối với từng xXcho một thuật ngữ kiểu P(x).

Thế còn ∃x ∈ X.P(x)? Chúng ta cần bất kỳ thành viên của X, xcùng với một bằng chứng P(x). Vì vậy, các thành viên (bằng chứng) của loại (mệnh đề) ∃x : X.P(x)là "cặp phụ thuộc": một thuật ngữ phân biệt xtrong X, cùng với một thuật ngữ loại P(x).

Ký hiệu: Tôi sẽ sử dụng

x  X...

cho các tuyên bố thực tế về các thành viên của lớp X

x : X...

cho các biểu thức loại tương ứng với định lượng phổ quát trên loại X. Tương tự như vậy cho .

Kết hợp cân nhắc: sản phẩm và tổng

Cũng như sự tương ứng của các loại Curry-Howard với các mệnh đề, chúng ta có sự tương ứng kết hợp của các loại đại số với các số và hàm, đây là điểm chính của câu hỏi này. Hạnh phúc, điều này có thể được mở rộng cho các loại phụ thuộc được nêu ở trên!

Tôi sẽ sử dụng ký hiệu mô-đun

|A|

để biểu thị 'kích thước' của một loại A, để làm rõ ràng sự tương ứng được nêu trong câu hỏi, giữa các loại và số. Lưu ý rằng đây là một khái niệm bên ngoài lý thuyết; Tôi không khẳng định rằng cần có bất kỳ nhà khai thác nào như vậy trong ngôn ngữ.

Hãy để chúng tôi đếm các thành viên có thể (giảm hoàn toàn, hợp quy)

x : X.P(x)

đó là loại hàm phụ thuộc lấy từ xloại này Xsang loại khác P(x). Mỗi hàm như vậy phải có đầu ra cho mỗi số hạng Xvà đầu ra này phải thuộc một loại cụ thể. Đối với mỗi xtrong X, sau đó, điều này mang lại |P(x)|'lựa chọn' đầu ra.

Phần cuối là

|∀x : X.P(x)| = Π[x : X]|P(x)|

điều này tất nhiên không có ý nghĩa lớn nếu XIO (), nhưng có thể áp dụng cho các loại đại số.

Tương tự, một thuật ngữ loại

x : X.P(x)

là loại cặp (x, p)với p : P(x), do đó, bất kỳ ai xtrong Xchúng ta cũng có thể xây dựng một cặp thích hợp với bất kỳ thành viên nào P(x), đưa ra |P(x)|'lựa chọn'.

Vì thế,

|∃x : X.P(x)| = Σ[x : X]|P(x)|

với những cảnh báo tương tự

Điều này biện minh cho ký hiệu phổ biến cho các loại phụ thuộc trong các lý thuyết bằng cách sử dụng các ký hiệu ΠΣthực tế, nhiều lý thuyết làm mờ sự khác biệt giữa 'cho tất cả' và 'sản phẩm' và giữa 'có' và 'tổng', do các tương ứng đã đề cập ở trên.

Chúng tôi đang đến gần!

Các vectơ: đại diện cho các bộ dữ liệu phụ thuộc

Bây giờ chúng ta có thể mã hóa các biểu thức số như

Σ[n  ℕ]X

như biểu thức kiểu?

Không hẳn. Mặc dù chúng ta có thể xem xét một cách không chính thức ý nghĩa của các biểu thức như Xⁿtrong Haskell, đâu Xlà loại và nsố tự nhiên, đó là sự lạm dụng ký hiệu; đây là biểu thức kiểu chứa một số: rõ ràng không phải là biểu thức hợp lệ.

Mặt khác, với các loại phụ thuộc trong ảnh, các loại chứa số chính xác là điểm; trong thực tế, các bộ dữ liệu phụ thuộc hoặc "vectơ" là một ví dụ rất phổ biến về cách các loại phụ thuộc có thể cung cấp sự an toàn ở mức loại thực dụng cho các hoạt động như truy cập danh sách . Một vectơ chỉ là một danh sách cùng với thông tin cấp độ liên quan đến độ dài của nó: chính xác những gì chúng ta đang theo dõi cho các biểu thức kiểu như thế nào Xⁿ.

Trong thời gian của câu trả lời này, hãy để

Vec X n

là loại nvectơ có độ dài của các Xgiá trị -type.

Về mặt kỹ thuật nở đây, chứ không phải là một số tự nhiên thực tế , một đại diện trong hệ thống của một số tự nhiên. Chúng ta có thể biểu diễn các số tự nhiên ( Nat) theo kiểu Peano là zero ( 0) hoặc người kế thừa ( S) của một số tự nhiên khác và đối với n ∈ ℕtôi viết ˻n˼có nghĩa là thuật ngữ Natđại diện n. Ví dụ, ˻3˼S (S (S 0)).

Sau đó chúng tôi có

|Vec X ˻n˼| = |X|ⁿ

cho bất kỳ n ∈ ℕ.

Nat loại: quảng bá ℕ điều khoản cho các loại

Bây giờ chúng ta có thể mã hóa các biểu thức như

Σ[n  ℕ]X

như các loại. Biểu thức cụ thể này sẽ làm phát sinh một loại tất nhiên là đồng hình với loại danh sách X, như được xác định trong câu hỏi. (Không chỉ có vậy, nhưng từ một điểm loại lý thuyết của xem, các loại chức năng - đó là một functor - dùng Xđể loại trên là một cách tự nhiên đẳng cấu lại danh sách functor.)

Một mảnh cuối cùng của câu đố cho các hàm 'tùy ý' là cách mã hóa, cho

f :   

biểu thức như

Σ[n  ℕ]f(n)X

để chúng ta có thể áp dụng các hệ số tùy ý cho một chuỗi lũy thừa.

Chúng ta đã hiểu sự tương ứng của các loại đại số với các số, cho phép chúng ta ánh xạ từ loại này sang số và loại hàm đến hàm số. Chúng ta cũng có thể đi một con đường khác! - lấy một số tự nhiên, rõ ràng có một loại đại số có thể xác định với nhiều thành viên hạn, cho dù chúng ta có loại phụ thuộc hay không. Chúng ta có thể dễ dàng chứng minh điều này bên ngoài lý thuyết loại bằng cảm ứng. Những gì chúng ta cần là một cách để ánh xạ từ số tự nhiên đến các loại, bên trong hệ thống.

Một nhận thức thú vị là, một khi chúng ta có các loại phụ thuộc, bằng chứng bằng cảm ứng và xây dựng bằng đệ quy trở nên giống nhau - thực sự chúng là những thứ rất giống nhau trong nhiều lý thuyết. Vì chúng ta có thể chứng minh bằng cách cảm ứng rằng các loại tồn tại đáp ứng nhu cầu của chúng ta, nên chúng ta không thể xây dựng chúng?

Có một số cách để thể hiện các loại ở cấp độ hạn. Tôi sẽ sử dụng ở đây một ký hiệu Haskellish tưởng tượng với *vũ trụ các loại, bản thân nó thường được coi là một loại trong một thiết lập phụ thuộc. 1

Tương tự như vậy, cũng có ít nhất nhiều cách để ghi chú ' tổng hợp' như có các lý thuyết loại phụ thuộc. Tôi sẽ sử dụng ký hiệu khớp mẫu Haskellish.

Chúng ta cần một ánh xạ, αtừ Natđến *, với thuộc tính

n  ℕ.|α ˻n˼| = n.

Các giả định sau đủ.

data Zero -- empty type
data Successor a = Z | Suc a -- Successor ≅ Maybe

α : Nat -> *
α 0 = Zero
α (S n) = Successor  n)

Vì vậy, chúng ta thấy rằng hành động αphản chiếu hành vi của người kế vị S, làm cho nó trở thành một loại đồng hình. Successorlà một hàm loại 'thêm một' vào số lượng thành viên của một loại; đó là, |Successor a| = 1 + |a|cho bất kỳ avới một kích thước xác định.

Ví dụ α ˻4˼(đó là α (S (S (S (S 0))))), là

Successor (Successor (Successor (Successor Zero)))

và các điều khoản của loại này là

Z
Suc Z
Suc (Suc Z)
Suc (Suc (Suc Z))

cho chúng tôi chính xác bốn yếu tố : |α ˻4˼| = 4.

Tương tự như vậy, đối với bất kỳ n ∈ ℕ, chúng ta có

 ˻n˼| = n

theo yêu cầu.

  1. Nhiều lý thuyết yêu cầu rằng các thành viên *chỉ là đại diện của các loại và một hoạt động được cung cấp dưới dạng ánh xạ rõ ràng từ các điều khoản của loại *đến các loại liên quan của chúng. Các lý thuyết khác cho phép bản thân các loại chữ là các thực thể cấp hạn.

Chức năng 'tùy ý'?

Bây giờ chúng ta có bộ máy để thể hiện một loạt sức mạnh tổng quát như một loại!

Bộ truyện

Σ[n  ℕ]f(n)X

trở thành kiểu

n : Nat f˼ n) × (Vec X n)

trong đó ˻f˼ : Nat → Natmột số đại diện phù hợp trong ngôn ngữ của chức năng f. Chúng ta có thể thấy điều này như sau.

|∃n : Nat f˼ n) × (Vec X n)|
    = Σ[n : Nat]|α f˼ n) × (Vec X n)|          (property of  types)
    = Σ[n  ℕ]|α f˼ ˻n˼) × (Vec X ˻n˼)|        (switching Nat for ℕ)
    = Σ[n  ℕ]|α ˻f(n × (Vec X ˻n˼)|           (applying ˻f˼ to ˻n˼)
    = Σ[n  ℕ]|α ˻f(n)˼||Vec X ˻n˼|              (splitting product)
    = Σ[n  ℕ]f(n)|X|ⁿ                           (properties of α and Vec)

Làm thế nào 'tùy tiện' là thế này? Chúng tôi không chỉ giới hạn ở các hệ số nguyên theo phương pháp này mà còn cả các số tự nhiên. Ngoài ra, fcó thể là bất cứ điều gì, với một ngôn ngữ Turing Complete với các loại phụ thuộc, chúng ta có thể biểu diễn bất kỳ hàm phân tích nào với các hệ số số tự nhiên.

Tôi đã không điều tra sự tương tác của điều này với, ví dụ, trường hợp được cung cấp trong câu hỏi List X ≅ 1/(1 - X)hoặc điều gì có thể có nghĩa là 'loại' âm và không nguyên có thể có trong bối cảnh này.

Hy vọng rằng câu trả lời này đi một số cách để khám phá chúng ta có thể đi bao xa với các hàm loại tùy ý.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.