Tôi không quan tâm đến định nghĩa đầu tiên - những định nghĩa đó sẽ không giúp tôi viết một chương trình thực sự (+1 nếu bạn thuyết phục tôi rằng tôi sai). Xin hãy giúp tôi hiểu định nghĩa thứ hai. Tôi nghĩ bản đồ, bộ lọc và thu nhỏ rất hữu ích: chúng cho phép tôi lập trình ở cấp độ cao hơn - ít lỗi hơn, mã ngắn hơn và rõ ràng hơn.
Hai định nghĩa về cơ bản là giống nhau. Đầu tiên là dựa trên định nghĩa chính thức và các ví dụ bạn đưa ra là các tổ hợp nguyên thủy - các khối xây dựng nhỏ nhất có thể. Họ có thể giúp bạn viết một chương trình thực trong chừng mực, với họ, bạn có thể xây dựng các tổ hợp phức tạp hơn. Hãy coi các tổ hợp như S và K là ngôn ngữ máy của một "máy tính tổ hợp" giả định. Tất nhiên, máy tính thực tế không hoạt động theo cách đó, vì vậy trong thực tế, bạn thường sẽ có các hoạt động cấp cao hơn được triển khai ở hậu trường theo những cách khác, nhưng nền tảng khái niệm vẫn là một công cụ hữu ích để hiểu ý nghĩa của những hoạt động cấp cao hơn đó. các hoạt động.
Định nghĩa thứ hai bạn đưa ra là không chính thức hơn và về việc sử dụng các tổ hợp phức tạp hơn, dưới dạng các hàm bậc cao hơn kết hợp các hàm khác theo nhiều cách khác nhau. Lưu ý rằng nếu các khối xây dựng cơ bản là các tổ hợp nguyên thủy ở trên, thì mọi thứ được xây dựng từ chúng đều là một hàm bậc cao hơn và cũng là một tổ hợp. Tuy nhiên, trong một ngôn ngữ mà các nguyên hàm khác tồn tại, bạn có sự phân biệt giữa những thứ có hoặc không phải là chức năng, trong trường hợp đó, tổ hợp thường được định nghĩa là một hàm thao tác các chức năng khác theo cách chung, thay vì hoạt động trên bất kỳ chức năng mọi thứ một cách trực tiếp.
Các ví dụ khác về các tổ hợp như bản đồ, bộ lọc là gì?
Quá nhiều để liệt kê! Cả hai đều biến đổi một hàm mô tả hành vi trên một giá trị đơn lẻ thành một hàm mô tả hành vi trên toàn bộ tập hợp. Bạn cũng có thể có các hàm chỉ chuyển đổi các hàm khác, chẳng hạn như soạn chúng từ đầu đến cuối hoặc tách và kết hợp các đối số. Bạn có thể có các tổ hợp biến các hoạt động một bước thành các hoạt động đệ quy tạo ra hoặc sử dụng các bộ sưu tập. Hoặc tất cả những thứ khác, thực sự.
Ngôn ngữ lập trình thường thực hiện những tổ hợp nào?
Điều đó sẽ thay đổi khá nhiều. Có tương đối ít các tổ hợp hoàn toàn chung chung - chủ yếu là các tổ hợp nguyên thủy được đề cập ở trên - vì vậy trong hầu hết các trường hợp, các tổ hợp sẽ có một số nhận thức về bất kỳ cấu trúc dữ liệu nào đang được sử dụng (ngay cả khi những cấu trúc dữ liệu đó được xây dựng từ các tổ hợp khác), trong đó trường hợp thường có một số ít các tổ hợp "hoàn toàn chung chung" và sau đó là bất kỳ hình thức chuyên biệt nào mà ai đó quyết định cung cấp. Có một số trường hợp vô lý trong đó (các phiên bản tổng quát phù hợp của) bản đồ, màn hình gập và mở ra là đủ để làm hầu hết mọi thứ bạn có thể muốn.
Làm cách nào để tổ hợp có thể giúp tôi thiết kế một API tốt hơn?
Chính xác như bạn đã nói, bằng cách suy nghĩ về các hoạt động cấp cao và cách chúng tương tác, thay vì các chi tiết cấp thấp.
Hãy nghĩ về mức độ phổ biến của các vòng lặp kiểu "for each" đối với các bộ sưu tập, cho phép bạn tóm tắt các chi tiết của việc liệt kê một bộ sưu tập. Đây chỉ là các thao tác ánh xạ / màn hình đầu tiên trong hầu hết các trường hợp và bằng cách tạo một tổ hợp (thay vì cú pháp tích hợp), bạn có thể thực hiện những việc như lấy hai vòng lặp hiện có và kết hợp trực tiếp chúng theo nhiều cách - lồng cái này vào bên trong cái kia, làm cái này đến cái kia, và cứ thế - bằng cách chỉ áp dụng một bộ tổ hợp, thay vì tung hứng cả đống mã xung quanh.
Làm cách nào để thiết kế tổ hợp hiệu quả?
Trước tiên, hãy nghĩ xem các thao tác nào có ý nghĩa trên bất kỳ dữ liệu nào mà chương trình của bạn sử dụng. Sau đó, hãy suy nghĩ về cách các hoạt động đó có thể được kết hợp một cách có ý nghĩa theo những cách chung, cũng như cách các hoạt động có thể được chia thành các phần nhỏ hơn được kết nối lại với nhau. Điều chính là làm việc với các phép biến đổi và hoạt động , không phải các hành động trực tiếp . Khi bạn có một chức năng chỉ thực hiện một số chức năng phức tạp theo cách không rõ ràng và chỉ tạo ra một số loại kết quả được tiêu hóa trước, bạn không thể làm gì nhiều với điều đó. Để lại kết quả cuối cùng cho mã sử dụng các tổ hợp - bạn muốn những thứ đưa bạn từ điểm A đến điểm B, không phải những thứ mong đợi là bắt đầu hoặc kết thúc của một quy trình.
Các tổ hợp tương tự như trong một ngôn ngữ phi chức năng (chẳng hạn như Java), hoặc những ngôn ngữ này sử dụng những gì thay cho các tổ hợp?
Ahahahaha. Bạn nên hỏi, vì các đối tượng thực sự là những thứ có bậc cao hơn ngay từ đầu - chúng có một số dữ liệu, nhưng chúng cũng thực hiện một loạt các hoạt động và khá nhiều thứ tạo nên thiết kế OOP tốt được tóm gọn lại thành "các đối tượng nên thường hoạt động giống như tổ hợp, không phải cấu trúc dữ liệu ".
Vì vậy, có lẽ câu trả lời tốt nhất ở đây là thay vì những thứ giống như tổ hợp, chúng sử dụng các lớp với nhiều phương thức getter và setter hoặc các trường công khai, và logic chủ yếu bao gồm thực hiện một số hành động không rõ ràng, được xác định trước.