Cách tổ chức các chương trình chức năng [đã đóng]


41

Có thể trùng lặp:
Lập trình chức năng so với OOP
Làm thế nào để viết mã có thể quản lý bằng lập trình chức năng?

Trong OOP, đơn vị tổ chức mã cơ bản của bạn là lớp. Một phương pháp được sử dụng thường xuyên trong Java, C # và các ngôn ngữ tương tự là tổ chức mã của bạn xung quanh việc có một tệp cho mỗi lớp với tên tệp theo tên lớp.

Bạn có thể coi mỗi lớp này là một đơn vị tổ chức để nhóm một khái niệm duy nhất.

Các lớp này nằm trong không gian tên thường theo cấu trúc thư mục của các tệp trong giải pháp / dự án. Không gian tên là một cấp độ khác của tổ chức.

Các dự án lớn trong các ngôn ngữ chức năng thường được tổ chức như thế nào?

Làm thế nào để bạn xác định làm thế nào để phân chia chức năng của bạn thành các tập tin khác nhau?

Các đơn vị khác của nhóm bên cạnh các tập tin được sử dụng?

Mã thường được tổ chức trong một tệp như thế nào?


18
@ S.Lott What's stopping you from...Nhiều năm và nhiều năm lập trình với một tư duy hoàn toàn khác, đến mức mã Haskell không tính toán được về mặt tinh thần. Và tất nhiên, bạn đang giả định rằng các dự án thực tế luôn được tổ chức chính xác và gọn gàng (có thể chúng là như thế nào nhưng một người mới như tôi biết?)
yannis

13
@ S.Lott: Tôi đã luôn lập trình trong OOP. Gần đây tôi đã bắt đầu học các ngôn ngữ chức năng vì tò mò. Bạn nói: "Tại sao hỏi ở đây?". Trả lời: Để nhận được một số lời khuyên và cái nhìn sâu sắc từ những người có kinh nghiệm (hoặc các chuyên gia như trang web đưa ra), người có thể khai sáng cho tôi về chủ đề này. Đó không phải là mục đích của trang web này sao? Không thể trả lời tất cả các câu hỏi của Lập trình viên hoặc SO: "tại sao bạn không tự mình tìm ra"? Câu trả lời là có, bạn có thể. Nhưng lý do để đặt câu hỏi là để có được kết quả tốt hơn / nhanh hơn từ một người là một chuyên gia về chủ đề này.
Gilles

5
@ S.Lott: nếu anh ta chỉ đọc mã ngẫu nhiên, làm sao anh ta biết liệu các quyết định tổ chức mà họ đưa ra là tốt hay xấu? Và tại sao họ tốt hay xấu?
Carson63000


4
@ S.Lott Tóm lại, có một chuyên gia về ngôn ngữ hoặc mô hình xác định một dự án được tổ chức tốt, xác định bất kỳ điểm yếu / thiếu sót nào có thể tồn tại trong tổ chức và giải thích tại sao có giá trị hơn nhiều so với việc chỉ đọc mã và nhìn vào tổ chức , với giả định rằng nó có cấu trúc tốt.
Thomas Owens

Câu trả lời:


32

Tôi nghi ngờ điều này phụ thuộc vào ngôn ngữ. Theo như lập trình chức năng, tôi chủ yếu tìm hiểu về Haskell, vì vậy tôi sẽ giải thích cách nó hoạt động ở đó.

Mã Haskell được tổ chức thành các "mô-đun" về cơ bản chỉ là tập hợp các hàm và kiểu dữ liệu. Mỗi mô-đun là một tập tin duy nhất. Một mô-đun là một thứ gì đó pha trộn giữa một lớp Java và một gói Java - phạm vi chính xác của những gì một mô-đun thực hiện khác nhau. Một mô-đun cũng có quyền kiểm soát các hàm và loại hàm xây dựng cần xuất và hàm nào cần ẩn; điều này tương tự privatepublictrong Java.

Trong các chương trình của riêng tôi, tôi muốn có các mô-đun làm một việc, về mặt ngữ nghĩa; điều này làm cho chúng giống như một lớp Java ngoại trừ việc chúng có thể định nghĩa nhiều loại dữ liệu. Các mô-đun tôi sử dụng từ thư viện tiêu chuẩn, giống Data.Listnhư các gói hơn - chúng cung cấp một tập hợp các hàm tiện ích tương tự. Điều này cũng rất giống với các lớp Java tĩnh như java.util.Arrays.

Các mô-đun cũng giống như các gói Java ở chỗ chúng có thể được lồng vào nhau cho rõ ràng (tôi không nghĩ rằng điều này có bất kỳ ảnh hưởng nào đến chính mã). Nói chung, đối với một dự án duy nhất, tôi đặt tên cho nó Projectvà nói rằng tất cả các mô-đun của tôi là một phần của điều này (ví dụ Project.ParseProject.Run). Nếu tôi đang viết mã giống như một thư viện hơn là một ứng dụng, tôi sẽ tổ chức nó dựa trên những gì nó đang làm, như Data.Listhoặc Control.Monad. Một điểm khác biệt lớn so với các ngôn ngữ khác là Haskell khuyến khích giới hạn IO và đặt tất cả ở một nơi. Một số lượng lớn các mô-đun hoàn toàn không có IO, và đối với bất kỳ dự án cụ thể nào, tôi muốn có càng nhiều mô-đun càng thuần càng tốt.

Ví dụ, tôi đang làm việc với một ngôn ngữ lập trình đơn giản mà tôi đang gọi TPL (không có lý do chính đáng). Để làm điều này, tôi đã tạo ra hai mô-đun đơn giản: TPL.Parsexác định biểu diễn bên trong của ngôn ngữ và cách phân tích cú pháp, và TPL.Runchạy trình thông dịch và xử lý các biến và IO. Để thực sự biên dịch và chạy mã, thường có một Mainmô-đun là điểm cuối cùng của chương trình.

Có sự tự do đáng kể trong việc tổ chức các chức năng trong một tệp; đây chỉ là những gì tôi muốn làm Tôi xác định các loại dữ liệu của mình về phía trên, trước khi chúng được sử dụng ở nơi khác. Ngay sau khi xác định các kiểu dữ liệu, tôi thực hiện bất cứ điều gì tôi cần để biến chúng thành một phần của kiểu chữ phù hợp của chúng - đây giống như việc thực hiện một giao diện. Sau đó, tôi làm theo logic và các chức năng trợ giúp khác nhau, khi thích hợp. Cuối cùng, tôi muốn có tất cả các chức năng IO của mình ở cuối cùng main. Điều này làm cho nó rõ ràng chính xác những gì đang làm bất kỳ IO và nơi chương trình bắt đầu.

Vì vậy, tóm lại: các hàm được chứa trong các mô-đun, mỗi hàm được tạo thành từ một tệp duy nhất. Một số mô-đun có thể tạo nên một chương trình hoặc thư viện; cái trước thường bao gồm một Mainmô-đun là điểm vào của nó. Trong một tệp, có các tùy chọn khác nhau cho tổ chức, nhưng tôi thích nhóm các loại dữ liệu gần đầu, IO gần cuối và logic ở giữa.

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.