Xin lỗi vì đã có một câu hỏi về tác dụng phụ khác của FP +, nhưng tôi không thể tìm thấy câu hỏi nào đã trả lời cho tôi.
Sự hiểu biết (hạn chế) của tôi về lập trình chức năng là các tác dụng phụ / trạng thái nên được giảm thiểu và tách biệt khỏi logic phi trạng thái.
Tôi cũng thu thập cách tiếp cận của Haskell về vấn đề này, đơn vị IO, đạt được điều này bằng cách gói các hành động có trạng thái trong một thùng chứa, để thực hiện sau này, được xem xét bên ngoài phạm vi của chính chương trình.
Tôi đang cố gắng để hiểu mẫu này, nhưng thực sự để xác định có nên sử dụng nó trong dự án Python hay không, vì vậy muốn tránh các chi tiết cụ thể của Haskell nếu có.
Ví dụ thô đến.
Nếu chương trình của tôi chuyển đổi một tệp XML thành một tệp JSON:
def main():
xml_data = read_file('input.xml') # impure
json_data = convert(xml_data) # pure
write_file('output.json', json_data) # impure
Không phải cách tiếp cận của đơn vị IO có hiệu quả để làm điều này:
steps = list(
read_file,
convert,
write_file,
)
sau đó tự giải phóng trách nhiệm bằng cách không thực sự gọi các bước đó, nhưng để người phiên dịch làm việc đó?
Hoặc nói cách khác, nó giống như viết:
def main(): # pure
def inner(): # impure
xml_data = read_file('input.xml')
json_data = convert(xml_data)
write_file('output.json', json_data)
return inner
sau đó mong đợi người khác gọi inner()
và nói rằng công việc của bạn đã hoàn thành bởi vì đó main()
là thuần túy.
Về cơ bản, toàn bộ chương trình sẽ được chứa trong đơn vị IO.
Khi mã được thực thi , mọi thứ sau khi đọc tệp phụ thuộc vào trạng thái của tệp đó, do đó vẫn sẽ gặp phải các lỗi liên quan đến trạng thái tương tự như việc triển khai bắt buộc, vậy bạn đã thực sự đạt được điều gì, với tư cách là một lập trình viên sẽ duy trì điều này?
Tôi hoàn toàn đánh giá cao lợi ích của việc giảm thiểu và cô lập hành vi trạng thái, đó là lý do tại sao tôi cấu trúc phiên bản bắt buộc như thế: thu thập dữ liệu đầu vào, làm công cụ thuần túy, nhổ đầu ra. Hy vọng convert()
có thể hoàn toàn tinh khiết và gặt hái những lợi ích của bộ nhớ cache, an toàn luồng, v.v.
Tôi cũng đánh giá cao rằng các loại đơn nguyên có thể hữu ích, đặc biệt là trong các đường ống hoạt động trên các loại tương đương, nhưng không hiểu tại sao IO nên sử dụng các đơn vị trừ khi đã có trong một đường ống như vậy.
Có một số lợi ích bổ sung để xử lý các tác dụng phụ mà mẫu đơn nguyên IO mang lại, mà tôi đang thiếu?
main
trong chương trình Haskell là IO ()
- một hành động IO. Đây thực sự không phải là một chức năng; đó là một giá trị . Toàn bộ chương trình của bạn là một giá trị thuần túy chứa các hướng dẫn cho biết thời gian chạy ngôn ngữ nên làm gì. Tất cả những thứ không trong sạch (thực sự thực hiện các hành động IO) nằm ngoài phạm vi chương trình của bạn.
read_file
) và sử dụng nó làm đối số cho phần tiếp theo ( write_file
). Nếu bạn chỉ có một chuỗi các hành động độc lập, bạn sẽ không cần Monad.