monads được mô tả là giải pháp haskell để xử lý IO. Tôi đã tự hỏi nếu có những cách khác để đối phó với IO trong ngôn ngữ chức năng tinh khiết.Thay thế các monads để sử dụng IO trong lập trình hàm thuần túy là gì?
Trả lời
Những lựa chọn thay thế cho mono cho I/O bằng ngôn ngữ chức năng thuần túy?
Tôi biết hai lựa chọn thay thế trong các tài liệu:
Một là một cái gọi là tuyến tính loại hệ thống. Ý tưởng là giá trị của loại tuyến tính phải được sử dụng chính xác một lần: bạn không thể bỏ qua nó và bạn không thể sử dụng nó hai lần. Với ý tưởng này, bạn cung cấp cho trạng thái của thế giới một loại trừu tượng (ví dụ:
World
) và bạn làm cho nó tuyến tính. Nếu tôi đánh dấu loại tuyến tính bằng dấu sao, thì dưới đây là các loại hoạt động I/O:getChar :: World* -> (Char, World*) putChar :: Char -> World* -> World*
v.v. Trình biên dịch sắp xếp để đảm bảo bạn không bao giờ sao chép thế giới, và sau đó nó có thể sắp xếp để biên dịch mã cập nhật thế giới tại chỗ, an toàn vì chỉ có một bản sao.
Cách nhập duy nhất bằng ngôn ngữ Clean dựa trên tuyến tính.
Hệ thống này có một số lợi thế; đặc biệt, nó không thực thi tổng số thứ tự trên các sự kiện mà monads làm. Nó cũng có xu hướng tránh "bin"
IO
"bạn thấy trong Haskell nơi tất cả tính toán hiệu quả được ném vào đơnIO
và tất cả chúng đều được đặt hàng hoàn toàn cho dù bạn muốn tổng số đơn đặt hàng hay không.Hệ thống khác Tôi nhận thức được xảy ra trước monads và sạch và được dựa trên ý tưởng rằng một chương trình tương tác là một chức năng từ một (có thể là vô hạn) chuỗi các yêu cầu đến một (có thể là vô hạn) chuỗi các phản hồi. Hệ thống này, được gọi là "hộp thoại", là địa ngục thuần túy để lập trình. Không ai nhớ nó, và nó không có gì đặc biệt để giới thiệu nó. Lỗi của nó được liệt kê độc đáo trong the paper that introduced monadic I/O (Imperative Functional Programming) bởi Wadler và Peyton Jones. Bài viết này cũng đề cập đến một hệ thống I/O dựa trên sự tiếp tục được giới thiệu bởi nhóm Yale Haskell nhưng nó đã tồn tại trong thời gian ngắn.
gõ độc đáo được sử dụng trong Clean
Nếu bằng cách "tinh khiết" bạn có nghĩa là "referentially minh bạch", có nghĩa là, rằng một chức năng áp dụng là tự do hoán đổi cho nhau với kết quả đánh giá của nó (và do đó mà gọi một hàm với cùng các đối số có cùng kết quả mỗi lần), bất kỳ khái niệm nào về trạng thái IO bị loại trừ khá nhiều theo định nghĩa.
Có hai chiến lược thô mà tôi biết:
Hãy một chức năng làm IO, nhưng chắc chắn rằng nó không bao giờ có thể được gọi hai lần với những lập luận chính xác cùng; vấn đề phụ này bằng cách cho phép các chức năng trở nên nhỏ gọn "tham chiếu trong suốt".
Điều trị toàn bộ chương trình dưới dạng một hàm thuần túy lấy "tất cả đầu vào nhận được" làm đối số và trả về "tất cả đầu ra được tạo", với cả hai biểu diễn dưới dạng luồng lười để cho phép tương tác.
Có nhiều cách để thực hiện cả hai cách tiếp cận, cũng như một số mức chồng chéo - ví dụ, trong trường hợp thứ hai, các chức năng hoạt động trên luồng I/O không được gọi hai lần cùng một phần của luồng. Cách nhìn vào nó có ý nghĩa hơn phụ thuộc vào loại hỗ trợ mà ngôn ngữ mang lại cho bạn.
Trong Haskell, IO
là một loại đơn nguyên tự động chủ đề tuần tự thông qua mã (tương tự như hàm tinh khiết State
monad), như vậy, về mặt khái niệm, mỗi cuộc gọi đến hàm khác không tinh khiết đều có giá trị khác nhau của ngầm "trạng thái của thế giới bên ngoài".
Cách tiếp cận phổ biến khác mà tôi biết là sử dụng một cái gì đó như linear types cho một kết thúc tương tự; đảm bảo rằng các hàm không tinh khiết không bao giờ nhận được cùng một đối số hai lần bằng cách có các giá trị không thể sao chép hoặc sao chép, do đó các giá trị cũ của "trạng thái của thế giới bên ngoài" không thể được giữ lại và sử dụng lại.
Imperative Functional Programming bởi Peyton Jones và Wadler là phải đọc nếu bạn quan tâm đến chức năng IO. Các phương pháp khác mà họ thảo luận là:
- Dialogues đó là suối lười biếng của phản ứng và yêu cầu
type Dialogue = [Response] -> [Request]
main :: Dialogue
continuations - mỗi hoạt động IO mất sự tiếp nối làm đối số
Kiểu tuyến tính - loại hệ thống hạn chế bạn theo cách mà bạn không thể sao chép hoặc phá hủy trạng thái bên ngoài, điều đó có nghĩa là bạn không thể gọi hàm hai lần với cùng trạng thái.
Ngoài các loại tuyến tính, cũng có effect system.
Functional Reactive Programming là một cách khác để xử lý việc này.
Tôi chưa từng nghe thuật ngữ "Lập trình phản ứng chức năng". Bạn có thể thay đổi nó thành "Lập trình phản ứng chức năng" không? Câu trả lời tuyệt vời khác. –
Không sao, cảm ơn vì đã chú ý. Không có ý tưởng làm thế nào tôi sai chính tả đó. –
- 1. "= 0;" là gì? làm gì khi khai báo các hàm ảo thuần túy trong C++?
- 2. Trình tự liên kết với các hàm thuần túy
- 3. Tại sao numCapabilities là một hàm thuần túy?
- 4. Điều gì thay thế mẫu MVC trong lập trình hàm?
- 5. Tránh IORef trong mã thuần túy
- 6. Trình điều khiển Java SQLiteJDBC thuần túy có thực sự thuần túy không?
- 7. Thay thế BGL lặp qua các đỉnh với thay thế C++ 11 "thuần túy"?
- 8. Thay thế BOOST_FOREACH bằng tùy chọn "thuần túy" C++ 11?
- 9. Lặp lại đánh giá biểu thức thuần túy trong hành động IO
- 10. Làm thế nào để thay thế chuỗi regex trong C thuần túy?
- 11. Chức năng thuần túy trong C++ 11
- 12. Chức năng thuần túy trong C#
- 13. Ứng dụng WebDAV thuần túy HTML WebDAV
- 14. Hết thời gian thực hiện các chức năng thuần túy
- 15. Làm thế nào để dòng mp3 bằng cách sử dụng Java thuần túy
- 16. Giá trị bên trong monads, được lồng trong cấu trúc dữ liệu?
- 17. Hiển thị văn bản thuần túy trong ứng dụng Android
- 18. Triển khai DOM trong javascript thuần túy?
- 19. Chức năng ảo thuần túy được gọi là
- 20. Có lý do nào tốt KHÔNG sử dụng jQuery thay vì JavaScript cũ thuần túy không?
- 21. Rõ ràng việc xác định thuần túy chức năng để sử dụng
- 22. Kết hợp các monads trong Haskell
- 23. việc sử dụng wchar_t trong lập trình chung là gì?
- 24. Cách yêu cầu bổ sung nhỏ? (cú pháp của các hàm ảo thuần túy)
- 25. Chức năng ảo thuần túy được gọi là lỗi
- 26. Bộ công cụ trực quan hóa Javascript, đồ họa thuần túy, nhanh nhất là gì?
- 27. Trường hợp sử dụng các chức năng ảo thuần túy với cơ thể?
- 28. Thêm các phần tử vào DOM cho HTML thuần văn bản chỉ sử dụng JavaScript thuần túy (không có jQuery)
- 29. Làm cách nào để tối ưu hóa từ "hàm thuần túy" trong C#?
- 30. Tại sao tôi không thể định nghĩa các hàm C thuần túy trong tệp tiêu đề?
Trình tự thông qua ràng buộc đơn nguyên là khá nhiều chỉ là kiểu được kiểm tra kiểu liên tục được kiểm tra kiểu, phải không? Ấn tượng của tôi là các monads và continuations hầu như có thể hoán đổi cho nhau, ngoại trừ việc các sự tiếp tục được quyết định không, nói chung, hoặc là ấm áp * hoặc * mờ. –
Continuations hình thành một đơn nguyên nhưng monads là decidedly * not * continuations. CPS là cách mạnh mẽ hơn bởi vì bạn được phép tạo bản sao của sự vật (bao gồm cả việc tiếp tục!). Monads hạn chế mọi thứ nghiêm trọng hơn nhiều so với việc kiểm tra kiểu đơn thuần. –
"Monads được quyết định không tiếp tục" - không, nhưng mối quan hệ không chỉ là một bản InstanceOf. Cf. http://lambda-the-ultimate.org/node/3235 Các lý thuyết và Monads, Hyland & Power, 2007. –