Trong Haskell, nó là thành ngữ để viết càng nhiều mã của bạn trong các hàm bậc cao hơn như nếp gấp, bản đồ và mở ra càng tốt. Vậy những loại mã nào không thể được viết với những hàm bậc cao hơn? Khi nào đệ quy rõ ràng cần thiết?Khi nào cần đệ quy rõ ràng?
Trả lời
Giả sử chúng tôi có ngôn ngữ không có đệ quy hoặc bất kỳ thứ gì giống như ngôn ngữ đó. Điều này có nghĩa là không có cấu trúc vòng lặp nào. Nó cũng có nghĩa là chúng ta có các loại (không đệ quy) để chúng ta không thể hình thành một bộ kết hợp Y và trốn thoát. Trong ngôn ngữ này, chúng tôi thực sự yếu, tách ra khỏi rất nhiều công cụ của chúng tôi.
Nhưng chúng tôi có thể đặt câu hỏi rất hay về ngôn ngữ này. Cụ thể, điều nhỏ nhất chúng ta phải đưa ra để nó trở nên mạnh mẽ như một ngôn ngữ không có những hạn chế như vậy là gì?
Hóa ra có hai câu trả lời.
Chúng tôi có thể giới thiệu chất kết dính đệ quy, giống như một lệnh
let rec
hoặc một cái gì đó giống nhưlet
Haskell mà luôn luôn làlet rec
. Nói cách khác, một cấu trúc cho phép chúng tôi xác địnhlet x = e in b
sao cho nếux
miễn phí tronge
thì nó được tính như một điểm cố định trên phương trìnhx = e
.Chúng tôi có thể giới thiệu chức năng
fix :: (a -> a) -> a
sao chofix f
giảm trong một bước đếnf (fix f)
.
Phải rõ ràng từ bản trình bày ở trên rằng fix
có thể được triển khai bằng cách sử dụng các trình kết nối đệ quy. Có gì một chút ít rõ ràng là chất kết dính đệ quy có thể được thực hiện từ những phi đệ quy sử dụng sửa chữa, nhưng ở đây chúng tôi là:
let x = fix $ \this -> e
Giá trị this
đề cập đến toàn bộ biểu hiện mà kết thúc ràng buộc như x
mà chỉ là những gì chúng tôi muốn.
Vậy tại sao tôi lại cố gắng nói tất cả những điều trên?
Về cơ bản, tôi muốn lập luận rằng không thể nói rằng đệ quy nhất thiết phải được thực hiện thông qua bộ kết hợp HOF như map
miễn là bạn sẵn sàng xem xét fix
trong danh sách đó. Tôi cũng muốn tranh luận rằng bất kỳ đệ quy nào được thực hiện bởi các combinators trong tập hợp đó có thể được thực hiện "một cách rõ ràng" bằng cách sử dụng các chất kết dính đệ quy. Chúng đều mạnh mẽ.
Phần thú vị có trong khi bạn xem xét các tổ hợp HOF như chính mình là foldr
/unfoldr
. Đây là những yếu tố kỹ thuật có phần là yếu hơn hơn fix
/các chất kết dính đệ quy. Ưu điểm là nếu bạn xây dựng một ngôn ngữ lập trình chỉ với một bộ lựa chọn là foldr
/unfoldr
nguyên tắc giống như vậy thì bạn có thể nhận được một ngôn ngữ hoàn chỉnh rất phong phú, có thể là tổng số hoặc được đảm bảo chấm dứt.
Tôi nghĩ rằng rất nhiều người tìm thấy các định nghĩa dữ liệu đệ quy dễ đọc hơn các loại Mu/Fix/Nu. Nó không hoàn toàn cần thiết, nhưng rất hữu ích ở đó.
Tương tự, bạn sẽ viết các trường hợp Có thể gập lại/Mở ra cho một kiểu dữ liệu như vậy bằng cách sử dụng đệ quy, nhưng khi chúng được cung cấp, đệ quy rõ ràng là không bắt buộc.
- 1. Khi nào chúng ta thực sự cần 'xvalues rõ ràng'?
- 2. Coq: Một ký hiệu trái đệ quy phải có một mức độ rõ ràng
- 3. Mẫu đệ quy polymer ràng buộc
- 4. Một giải thích rõ ràng hơn cho đệ quy và luồng thực thi trong JavaScript?
- 5. là trình diễn mẫu có thể đệ quy rõ ràng có thể?
- 6. tìm mà không cần đệ quy
- 7. Đệ quy đệ quy so với đệ quy trước
- 8. Đệ quy đệ quy và đệ quy đệ quy trong Erlang
- 9. Loài đệ quy đệ quy với asyncio
- 10. Giao tiếp đệ quy đệ quy giữa các đa giác
- 11. Có cần khôi phục giao dịch rõ ràng không?
- 12. Khi nào nên sử dụng mutex đệ quy?
- 13. Rõ ràng màn hình trước khi nổ
- 14. Làm thế nào để ngăn chặn AngularJS ràng buộc đệ quy?
- 15. Ngăn chặn việc thực thi đệ quy đệ quy?
- 16. Thuật toán hoán vị mà không cần đệ quy? Java
- 17. EXC_BAD_ACCESS khi sử dụng khối đệ quy
- 18. Đệ quy đệ quy khi serializing các đối tượng với Jackson và Mockito
- 19. Subimplicits rõ ràng
- 20. UpdateSourceTrigger = Rõ ràng
- 21. Tại sao rõ ràng std :: di chuyển là cần thiết khi trở về loại tương thích?
- 22. Làm đệ quy đệ quy bộ nhớ rò rỉ?
- 23. Viết lại một hàm đệ quy mà không sử dụng đệ quy
- 24. multiprocessing.value rõ ràng cú pháp?
- 25. Chuyển đổi thành vòng lặp ... đệ quy đệ quy
- 26. Tôi có cần kiểm tra rõ ràng __name__ == "__main__" trước khi gọi getLogger bằng Python không?
- 27. staticmethod và đệ quy?
- 28. Sed thay đệ quy
- 29. Không đệ quy os.walk()
- 30. JTextPane văn bản rõ ràng
Bạn có hỏi khi nào đệ quy là * cần thiết * hay khi đó là * thành ngữ *? Tiêu đề của bạn nói đầu tiên; câu cuối cùng của bạn nói câu thứ hai. –
Điểm tốt. Tôi đã tự hỏi cả hai, nhưng tôi sẽ giới hạn nó thành một câu hỏi: Khi nào thì đệ quy rõ ràng thực sự cần thiết? Tôi sẽ chỉnh sửa câu hỏi. –
Các hàm bậc cao hơn như 'map' và' fold' được thực hiện với đệ quy. Nếu bạn đang sử dụng chúng, ngữ nghĩa, bạn đang sử dụng đệ quy. Cú pháp, bạn không bao giờ phải sử dụng đệ quy, ngoại trừ một lần - để xác định "hàm đệ quy chuẩn" - 'fix f = let x = f x trong x'. – user2407038