Là lý thuyết thể loại hữu ích cho việc học lập trình chức năng?


118

Tôi đang học Haskell và tôi bị mê hoặc bởi ngôn ngữ này. Tuy nhiên tôi không có nền tảng toán học hay CS nghiêm túc. Nhưng tôi là một lập trình viên phần mềm có kinh nghiệm.

Tôi muốn học lý thuyết thể loại để tôi có thể trở nên tốt hơn tại Haskell.

Những chủ đề nào trong lý thuyết thể loại tôi nên học để cung cấp một cơ sở tốt để hiểu Haskell?



1
Tôi đánh giá cao rằng bạn phân biệt lập trình và cs.
jmite

4
"Lý thuyết phạm trù học tập để trở nên tốt hơn ở Haskell" giống như "Học vật lý để trở nên tốt hơn trong quần vợt"
user26756

Câu trả lời:


115

Trong một câu trả lời trước đây trong trang web Khoa học máy tính lý thuyết , tôi đã nói rằng lý thuyết phạm trù là "nền tảng" cho lý thuyết loại. Ở đây, tôi muốn nói một cái gì đó mạnh mẽ hơn. Lý thuyết phạm trù là lý thuyết loại . Ngược lại, lý thuyết loại là lý thuyết thể loại . Hãy để tôi mở rộng về những điểm này.

Lý thuyết loại là lý thuyết loại

Trong bất kỳ ngôn ngữ chính thức đánh máy, và thậm chí cả trong toán học bình thường sử dụng ký hiệu không chính thức, chúng tôi kết thúc chức năng tuyên bố với các loại . Ẩn ý trong văn bản đó là ý tưởng rằng và là một số thứ gọi là "loại" và là "hàm" từ loại này sang loại khác. Lý thuyết phạm trù là lý thuyết đại số của các "loại" và "hàm" như vậy. (Chính thức, lý thuyết phạm trù gọi chúng là "đối tượng" và "hình thái" để tránh giẫm lên các ngón chân lý thuyết tập hợp của các nhà truyền thống, nhưng ngày càng tôi thấy các nhà lý thuyết phạm trù ném gió như vậy và sử dụng thuật ngữ trực quan hơn: " "và" chức năng ". Nhưng,A B ff:ABABf

Tất cả chúng ta đã được đưa lên trên lý thuyết tập hợp từ trường trung học trở đi. Vì vậy, chúng ta thường nghĩ về các loại như và là tập hợp và các hàm như là ánh xạ lý thuyết tập hợp. Nếu bạn không bao giờ nghĩ về họ theo cách đó, bạn đang ở trong tình trạng tốt. Bạn đã thoát khỏi việc rửa não theo lý thuyết tập hợp. Lý thuyết phạm trù nói rằng có nhiều loại và nhiều loại chức năng. Vì vậy, ý tưởng về các loại như bộ là hạn chế. Thay vào đó, lý thuyết thể loại axiomatized các loại và chức năng theo cách đại số. Về cơ bản, đó là những gì lý thuyết thể loại. Một lý thuyết về các loại và chức năng. Nó khá phức tạp, liên quan đến mức độ trừu tượng cao. Nhưng, nếu bạn có thể học nó, bạn sẽ có được sự hiểu biết sâu sắc về các loại và chức năng.B fABf

Lý thuyết loại là lý thuyết thể loại

Theo "lý thuyết loại", ý tôi là bất kỳ loại ngôn ngữ chính thức nào được đánh máy, dựa trên các quy tắc cứng nhắc về hình thành thuật ngữ để đảm bảo rằng mọi thứ đều kiểm tra. Nó chỉ ra rằng, bất cứ khi nào chúng ta làm việc trong một ngôn ngữ như vậy, chúng ta đang làm việc trong một cấu trúc lý thuyết thể loại. Ngay cả khi chúng ta sử dụng các ký hiệu lý thuyết tập hợp và suy nghĩ theo lý thuyết tập hợp, cuối cùng chúng ta vẫn viết những thứ có ý nghĩa phân loại. Đó là một sự thật tuyệt vời .

Trong lịch sử, Dana Scott có thể là người đầu tiên nhận ra điều này. Ông đã làm việc để tạo ra các mô hình ngữ nghĩa của các ngôn ngữ lập trình dựa trên phép tính lambda được gõ (và chưa được gõ). Các mô hình lý thuyết tập hợp truyền thống không phù hợp cho mục đích này, bởi vì các ngôn ngữ lập trình liên quan đến đệ quy không giới hạn, điều này đặt ra lý thuyết thiếu. Scott đã phát minh ra một loạt các mô hình ngữ nghĩa nắm bắt các hiện tượng lập trình và nhận ra rằng tính toán lambda đã thể hiện chính xác một lớp các thể loại được gọi là các thể loại đóng cartesian . Có rất nhiều thể loại đóng cartesian không phải là "lý thuyết tập hợp". Nhưng tính toán lambda đánh máy áp dụng cho tất cả chúng như nhau. Scott đã viết một bài luận hay gọi là " Liên quan đến lý thuyết của phép tính lambda"giải thích những gì đang diễn ra, những phần dường như có sẵn trên web. Bài báo gốc đã được xuất bản trong một tập có tên" To HB Curry: Essays on Combinatory Logic, Lambda Tính và Chủ nghĩa hình thức ", Nhà xuất bản Học thuật, 1980. Berry và Curien đã nhận ra cùng một nhận thức, có lẽ là độc lập. Họ đã định nghĩa một cỗ máy trừu tượng phân loại (CAM) để sử dụng những ý tưởng này trong việc thực hiện các ngôn ngữ chức năng và ngôn ngữ mà họ triển khai được gọi là "CAML", là khung cơ bản của F # của Microsoft .

Các hàm tạo kiểu chuẩn như , , , v.v. là hàm functor . Điều đó có nghĩa là chúng không chỉ ánh xạ các loại thành các loại, mà còn các chức năng giữa các loại thành các chức năng giữa các loại. Các hàm đa hình bảo toàn tất cả các hàm như vậy do các hành động của functor. Lý thuyết thể loại được phát minh vào những năm 1950 bởi Eilenberg và MacLaneL i s t×Listchính xác để chính thức hóa khái niệm về chức năng đa hình. Họ gọi chúng là "biến đổi tự nhiên", "tự nhiên" bởi vì chúng là những biến đổi duy nhất mà bạn có thể viết theo cách đúng loại bằng cách sử dụng biến kiểu. Vì vậy, người ta có thể nói rằng lý thuyết thể loại đã được phát minh chính xác để chính thức hóa các ngôn ngữ lập trình đa hình, ngay cả trước khi các ngôn ngữ lập trình ra đời!

Một nhà truyền thống lý thuyết tập hợp không có kiến ​​thức về functor và các biến đổi tự nhiên đang diễn ra dưới bề mặt khi anh ta sử dụng các ký hiệu lý thuyết tập hợp. Nhưng, miễn là anh ta sử dụng hệ thống loại một cách trung thực, anh ta thực sự đang thực hiện các công trình phân loại mà không nhận thức được chúng.


Tất cả đã nói và làm, lý thuyết phạm trù là lý thuyết toán học tinh túy về các loại và chức năng. Vì vậy, tất cả các lập trình viên có thể hưởng lợi từ việc học một chút về lý thuyết thể loại, đặc biệt là các lập trình viên chức năng. Thật không may, dường như không có bất kỳ cuốn sách văn bản nào về lý thuyết thể loại nhắm vào các lập trình viên cụ thể. Các cuốn sách "lý thuyết thể loại cho khoa học máy tính" thường được nhắm mục tiêu vào các sinh viên / nhà nghiên cứu khoa học máy tính lý thuyết. Cuốn sách của Benjamin Pierce, lý thuyết thể loại cơ bản cho các nhà khoa học máy tính có lẽ là cuốn sách dễ đọc nhất trong số đó.

Tuy nhiên, có rất nhiều tài nguyên trên web, được nhắm mục tiêu vào các lập trình viên. Các trang Haskellwiki có thể là một điểm khởi đầu tốt. Tại trường đại học Midlands , chúng tôi có các bài giảng về lý thuyết thể loại (trong số những người khác). Khóa học của Graham Hutton được chốt là khóa học "người mới bắt đầu" và khóa học của tôi được chốt là khóa học "nâng cao". Nhưng cả hai đều bao gồm về cơ bản cùng một nội dung, đi đến độ sâu khác nhau. Đại học Chalmers có một trang tài nguyên tuyệt vời về sách và ghi chú bài giảng từ khắp nơi trên thế giới. Trang blog nhiệt tình của "sigfpe" cũng cung cấp rất nhiều trực giác tốt theo quan điểm của một lập trình viên.

Các chủ đề cơ bản bạn muốn tìm hiểu là:

  • định nghĩa về danh mục và một số ví dụ về danh mục
  • functor, và ví dụ về họ
  • biến đổi tự nhiên, và ví dụ về chúng
  • định nghĩa về sản phẩm, sản phẩm sao chép và số mũ (không gian chức năng), đối tượng ban đầu và thiết bị đầu cuối.
  • điều chỉnh
  • các loại đơn nguyên, đại số và Kleisli

Ghi chú bài giảng của riêng tôi trong Trường Cao học Midlands bao gồm tất cả các chủ đề này ngoại trừ chủ đề cuối cùng (đơn nguyên). Có rất nhiều tài nguyên khác có sẵn cho các đơn vị ngày nay. Vì vậy, đó không phải là một mất mát lớn.

Càng biết nhiều toán học, bạn càng dễ học lý thuyết phạm trù. Bởi vì lý thuyết phạm trù là một lý thuyết chung về cấu trúc toán học, thật hữu ích khi biết một số ví dụ để đánh giá cao ý nghĩa của các định nghĩa. (Khi tôi học lý thuyết thể loại, tôi phải tạo ra các ví dụ của riêng mình bằng kiến ​​thức về ngữ nghĩa ngôn ngữ lập trình, bởi vì sách giáo khoa tiêu chuẩn chỉ có các ví dụ toán học, mà tôi không biết gì về nó.) và Scott gọi là " Giới thiệu về logic phân loại"lý thuyết thể loại liên quan đến loại hệ thống (cái mà họ gọi là" logic "). Giờ đây có thể hiểu lý thuyết thể loại chỉ bằng cách liên hệ nó với hệ thống loại ngay cả khi không biết nhiều ví dụ. Rất nhiều tài nguyên tôi đã đề cập ở trên sử dụng cách tiếp cận để giải thích lý thuyết thể loại.


3
@UdayReddy Tôi hoàn toàn không đồng ý với việc bạn xác định lý thuyết danh mục với lý thuyết loại. Lý thuyết loại hiện đại liên tục về các loại cho các quy trình đồng thời, ví dụ truyền thống lý thuyết về các loại phiên. Theo hiểu biết tốt nhất của tôi, không có sự hiểu biết phân loại về các hệ thống gõ như vậy.
Martin Berger

6
@MartinBerger Tôi nghĩ cách giải thích của bạn về "lý thuyết loại" hơi hẹp. Tuy nhiên, tôi đồng ý rằng một sự hiểu biết đúng về lý thuyết và lý thuyết loại về các loại phiên hiện đang là một thách thức nghiên cứu tốt, một điều mà tôi dự định sẽ dành thời gian cho nó.
Uday Reddy

2
@MartinBerger. Để xem lý thuyết thể loại áp dụng như thế nào đối với các khái niệm tính toán phong phú hơn, tôi mời bạn xem xét cách nó được áp dụng cho lý thuyết lập trình mệnh lệnh và ngữ nghĩa trò chơi (một lần nữa có thể mã hóa các tính toán bắt buộc khá tốt). Vì vậy, tôi không tin rằng lập trình chức năng có độc quyền về lý thuyết thể loại.
Uday Reddy

1
@nicolas, fibrations là một cách để thực hiện các danh mục được lập chỉ mục, loại mô hình phụ thuộc. Fibrations cũng có thể được xem như là một hình thức rất tổng quát của chương trình logic, nơi có nghĩa là bản đồ giá trị -satisfying để giá trị -satisfying. f P Qf:PQfPQ
Uday Reddy

2
"Thật không may, dường như không có bất kỳ cuốn sách văn bản nào về lý thuyết thể loại nhắm vào các lập trình viên cụ thể." Một "cuốn sách văn bản" như vậy bây giờ ít nhiều tồn tại trong Lý thuyết Danh mục dành cho lập trình viên của Bartosz Milewski . Bartosz cũng đã tạo ra một chuỗi bài giảng đi kèm .
alx9r

30

Tôi sẽ cố gắng để giữ cho nó ngắn và ngọt ngào. Có một sự tương ứng không chính thức giữa các chương trình Haskell và các loại danh mục nhất định, có thể được thực hiện chính thức hơn với một số công việc. Sự tương ứng này được gọi là thư từ Curry-Howard-Lambek và liên quan:

  1. Các loại Haskell với các đối tượng của thể loại
  2. Điều khoản của loại với hình thái (lưu ý các ký hiệu tương tự)f : A BAB f:AB
  3. Các kiểu dữ liệu đại số với các đối tượng ban đầu
  4. Gõ constructor với functor
  5. Vân vân

Danh sách này cứ lặp đi lặp lại, nhưng một điểm cốt yếu là bạn có thể định nghĩa những thứ như monadđại số trong lý thuyết thể loại và đưa ra những khái niệm vừa hữu ích cho các nhà toán học nhưng cũng có sức lan tỏa trong thực tiễn lập trình Haskell.

Tôi không chắc nên giới thiệu cuốn sách nào, vì tôi chưa tìm thấy một cuốn sách giới thiệu hoàn toàn thỏa đáng về các danh mục cho các nhà khoa học máy tính. Bạn có thể thử Danh mục, Loại và Cấu trúc của Asperti và Longo. Ý tưởng là học các định nghĩa cơ bản cho đến các điều chỉnh, và sau đó có thể thử và đọc một số blog tuyệt vời ngoài kia để thử và hiểu các khái niệm này.


1
"đưa ra các khái niệm vừa hữu ích cho các nhà toán học nhưng cũng có sức lan tỏa trong thực hành lập trình Haskell" - bạn có thể đưa ra một ví dụ, hoặc điều đó đòi hỏi quá nhiều kiến ​​thức trước?
Raphael

7
@Raphael: Monads. Mũi tên. Đại số. Coachebras.
Dave Clarke

6
Functor, duality, thể loại Kleisli, bổ đề Yoneda ...
cody

4
Cartesion loại kín. Cà ri.
Dave Clarke

2
"Giới thiệu về Lý thuyết Danh mục dành cho Kỹ sư phần mềm", cs.toronto.edu/~sme/presentations/cat101.pdf
Vladimir Alexiev

29

Echoing lời khuyên @AJed, tôi khuyên bạn nên chuyển tuyên bố của mình

I want to learn category theory so I can become better at Haskell.

trên đầu của nó: tìm hiểu Haskell, dựa trên trực giác lập trình của bạn. Khi bạn là một chuyên gia về FP, có thể dễ dàng hơn để chọn lý thuyết danh mục (nếu bạn vẫn quan tâm).

Lý thuyết danh mục là đơn giản cho ai đó có giáo dục toán học rộng (nhóm, vòng, mô-đun, không gian vectơ, cấu trúc liên kết, v.v.). Thiếu nền tảng này, lý thuyết thể loại gần như không thể xuyên thủng. Cái hay của lý thuyết phạm trù là nó hợp nhất rất nhiều thứ dường như không liên quan (ví dụ: sự điều chỉnh bên trái của các functor quên bao gồm các nhóm miễn phí, đại số bao bọc phổ quát, nén chặt Stone-Cech, xóa bỏ các nhóm, ...), và do đó làm giảm sự phức tạp. Nhưng nếu bạn không quen thuộc với nhiều ví dụ mà lý thuyết thể loại thống nhất, thì lý thuyết phạm trù chỉ là một lớp phức tạp bổ sung khiến cuộc sống của bạn trở nên khó khăn hơn.

Theo kinh nghiệm của tôi, học tập dễ dàng hơn bằng cách xây dựng trên những điều người ta đã biết. Là một nhà phát triển phần mềm, bạn biết rất nhiều về lập trình và lập trình Haskell không khác với lập trình khác, vì vậy tôi khuyên bạn nên tiếp cận Haskell từ quan điểm lập trình thực dụng, bỏ qua lý thuyết danh mục. Một chút của lý thuyết thể loại trong Haskell, ví dụ như một số hỗ trợ cho các đơn vị, dễ dàng hơn nhiều cho một lập trình viên để nắm bắt mà không cần đi đường vòng qua lý thuyết thể loại. Xét cho cùng, các đơn nguyên chỉ là thành phần tổng quát (và bạn sẽ sử dụng các đơn vị trong thực tiễn lập trình của mình - mặc dù không biết bạn đã làm gì) và Haskell không thực sự hỗ trợ các đơn vị thực sự, vì nó không thực thi luật pháp đơn nguyên.


7
Không, phải trung thực Haskell thực sự có khác biệt so với hầu hết các ngôn ngữ lập trình khác, đến mức nhận định kiến quá khứ thường là thách thức lớn nhất. Các nhà phát triển phần mềm có kinh nghiệm dường như gặp nhiều rắc rối hơn những người chưa từng lập trình trước đây.
CA McCann

5
@CAMcCann Tôi đồng ý rằng một số chương trình có kinh nghiệm dường như gặp khó khăn khi chuyển từ ví dụ Java hoặc C # sang Haskell, nhưng tôi không nghĩ đó là vì có gì đó khác biệt về Haskell. Tôi nghĩ đó là một phần bởi vì nó có vẻ khác nhau. Ý tưởng rằng bạn cần học lý thuyết danh mục để đánh giá cao Haskell có lẽ đã ngăn cản khá nhiều nhà phát triển phần mềm có kinh nghiệm đạt được thành thạo Haskell. (Cf. tại sao F # không có đơn nguyên.) Tôi chắc chắn thấy khó nghĩ về nhiều tính năng của Haskell cũng không giống với các ngôn ngữ khác.
Martin Berger

5
Biết Lý thuyết Danh mục có thể giúp một chút, nhưng không nhiều, và học chắc chắn khó hơn nhiều so với học Haskell. Có nhiều sự khác biệt cơ bản so với hầu hết các ngôn ngữ (độ tinh khiết, đánh giá không nghiêm ngặt, hệ thống loại) và loại bỏ tất cả các thuật ngữ CT không làm cho những điều này trở nên quen thuộc hơn. Mặt khác, học Haskell thúc đẩy một số người học một số CT, bởi vì những ý tưởng mượn là hữu ích . Hệ thống loại hạn chế của F # và tránh một thuật ngữ hoàn toàn tốt hiện có là sai sót, không phải là tính năng.
CA McCann

1
Tôi không biết bất kỳ ngôn ngữ nào ngoài Scala với hệ thống loại thực sự có thể so sánh với Haskell. Từ quan sát thực nghiệm, độ tinh khiết không được nắm bắt ngay lập tức và đánh giá không nghiêm ngặt (mà bạn bỏ qua) thậm chí còn khó hơn. Cuối cùng, tôi một lập trình viên làm việc và tôi tranh luận rằng bất kỳ ai trong lĩnh vực này sẽ bị đe dọa bởi một cái tên . Các ngành công nghiệp phát triển phần mềm đã đầy những thuật ngữ mờ đục rồi. Ngoài ra, hệ thống loại của F # không thể biểu thị trực tiếp các đơn nguyên - biểu thức tính toán không phải là lớp đầu tiên, điều này hạn chế đáng kể việc sử dụng chúng.
CA McCann

2
CBN cũng dễ dàng về mặt khái niệm, ví dụ bằng cách tương tự với thunking, một khái niệm mà hầu hết các lập trình viên làm việc sẽ sử dụng trước đây. Sự tinh khiết là điều mà mọi lập trình viên làm việc đều hiểu. Haskell được sử dụng trong giáo dục đại học ở Anh. Khi sinh viên của tôi hỏi tôi làm thế nào để vào lập trình chức năng, tôi thường khuyên bạn nên học Haskell trước, nhưng sinh viên bị đe dọa bởi danh tiếng của nó, cũng như người khởi tạo câu hỏi. Tôi tin rằng lý do chính cho điều này là sự liên kết của Haskell với lý thuyết thể loại.
Martin Berger

13

Một câu trả lời ngắn gọn: không [nhưng đây chỉ là một ý kiến]

Đừng đi đến Lý thuyết Danh mục hoặc bất kỳ lĩnh vực lý thuyết nào khác để trở nên tốt trong Haskell. Tìm hiểu các kỹ thuật lập trình chức năng, chẳng hạn như đệ quy đuôi, bản đồ, thu nhỏ và các kỹ thuật khác. Đọc càng nhiều mã càng tốt. Thực hiện càng nhiều ý tưởng càng tốt. Nếu bạn có vấn đề, đọc và đọc.

Nếu bạn muốn có một tài liệu tham khảo lý thuyết tốt để tìm hiểu Haskell và các mô hình lập trình chức năng khác thì hãy xem: Giới thiệu về lập trình chức năng thông qua Lambda Tính, Greg Michaelson (có sẵn trực tuyến). ... Có những cuốn sách tương tự khác.


1
Tôi nhướn mày vì điều này vì "đệ quy đuôi" thường không quan trọng để lập trình trong Haskell do sự lười biếng. Tuy nhiên, "học bằng cách làm" hầu như luôn luôn là lời khuyên tốt.
Dan Burton

@DanBurton .. quan sát thú vị. Hãy nói sau đó, thay vì Haskell, hãy học erlang hoặc lược đồ :). [Tôi không phải là chuyên gia về Haskell, tôi chỉ chọn nó vì nó nghe hay]
AJed


0

Lý thuyết phạm trù là một nhánh rất phức tạp của toán học và việc thành thạo nó sẽ thống nhất hầu hết các bài học trước đây của bạn bằng cách biến chúng thành các thể hiện của cùng một đối tượng trừu tượng. Vì vậy, nó rất hữu ích và rất trực quan. Nhưng nó rộng lớn và rộng lớn, và bạn sẽ thấy mình có rất nhiều khái niệm mới thậm chí sẽ không biết cái nào phù hợp với nhu cầu của bạn và cái nào bạn nên bỏ qua. Vì vậy, cách tiếp cận có mục đích của bạn cần sự lựa chọn giữa các khái niệm, nếu không, việc thành thạo nó chắc chắn cần thời gian dài và thực sự không phải là một lĩnh vực tự học.

Nhân tiện, tôi đề nghị một điểm khởi đầu rất tốt cho mục đích của bạn là ở đây .


Điều này không thực sự trả lời câu hỏi: nó có hữu ích cho việc học lập trình chức năng không? Những chủ đề trong lý thuyết thể loại là hữu ích cho Haskell?
David Richerby
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.