2010-08-14 60 views
8
  • Tôi đã tự hỏi: các vòng lặp vô hạn có thể được thực hiện trong lập trình hàm không?

ví dụ: khi sử dụng API cửa sổ để nhận thông báo cửa sổ, nó thường được triển khai trong một vòng lặp.vòng lặp vô hạn trong lập trình chức năng?

Tôi biết có thể thực hiện một chức năng sẽ tiếp tục đi vào đệ quy vô thời hạn. Tôi hy vọng rằng điều này sẽ dẫn đến tràn ngăn xếp.

  • là vòng lặp vô hạn sai ý tưởng đặt cho lập trình hàm?

  • là giao diện của hệ điều hành hoặc phần cứng là vấn đề?

dường như tôi không giống chương trình chức năng/o.s. có thể tiếp tục chạy một mình

Tôi có một chút kinh nghiệm viết các chương trình chức năng nhưng điều này luôn làm phiền tôi. hãy chia sẻ suy nghĩ/thông tin chi tiết của bạn về những vấn đề này

+2

Hãy thử googling 'đệ quy đuôi'. – sje397

+0

cảm ơn bạn đã nhập mọi người – symbiont

Trả lời

4

Như những người khác đã được đăng, một vòng lặp vô hạn có thể thông qua tail recursions.

Ví dụ: loop() sẽ chạy một cách hiệu quả như một vòng lặp vô hạn (trong không gian ngăn xếp không đổi) vì trình biên dịch có thể tối ưu hóa cuộc gọi đuôi đệ quy của loop ở cuối.

let loop() = do { 
    println("foo") 
    loop() 
} 

Nhưng

là vòng lặp vô hạn sai tâm-thiết cho chức năng lập trình?

vẫn có điểm. Hãy xem xét ví dụ về Windows-API của bạn với vòng lặp vô hạn. Đó là bất cứ điều gì nhưng chức năng.Hãy nhớ - chức năng có nghĩa là suy nghĩ trong các giá trị (và ý nghĩa của chúng là). Do đó, người ta thà đi một/cách tiếp cận dựa trên sự kiện phản ứng như thế [Pseudo code chức năng]

(onClick form1) 
|> Event.subscribe (\pt-> do { print $ "I was clicked at " ++ (show pt) }) 

Vì vậy

nó không có vẻ với tôi như một chương trình chức năng/o.s. có thể tiếp tục chạy tự

kỹ thuật sai - bạn thể thực hiện vòng lặp vô hạn - nhưng thường có không (chức năng) điểm khi làm như vậy. Tại sao một người cần điều đó ngoại trừ một số loại bỏ phiếu IO? Việc biến đổi các giá trị theo cách hoàn toàn chức năng sẽ chấm dứt để có ý nghĩa.

+0

thú vị. tôi đã không nghĩ rằng lập trình chức năng có thể nhận được ngay với những cuộc truy tìm vô hạn (tốt để biết). cảm ơn thông tin và thông tin chi tiết của bạn. tôi thích ý tưởng lập trình phản ứng. – symbiont

+0

Ví dụ về lý do tại sao bạn làm điều này: Phần lõi của chương trình thường được biểu diễn tốt nhất như là một chuỗi biến đổi vô hạn tiềm tàng trong trạng thái thế giới (ví dụ Pac-Man sắp ăn viên, Pac-Man là một bước lên và đã ăn viên thuốc, vv). Đây cũng là trường hợp phổ biến nhất cho các vòng vô hạn trong trải nghiệm của tôi. – Chuck

1

Bạn có thể có vô hạn tail recursion nếu trình biên dịch của bạn nhận ra nó. Một số ngôn ngữ, ví dụ: lược đồ, yêu cầu các trình biên dịch nhận ra đệ quy đuôi và phân bổ không gian ngăn xếp cho nó.

Chỉnh sửa Tôi không có ý kiến ​​không đồng ý với các câu trả lời khác, nhưng vòng lặp đệ quy "vô hạn" là một thành ngữ phổ biến để xử lý thế giới bên ngoài. Ví dụ sau được lấy từ Real World Haskell và là đại diện của thành ngữ.

mainloop :: Handle -> Handle -> IO() 
mainloop inh outh = 
    do ineof <- hIsEOF inh 
     if ineof 
      then return() 
      else do inpStr <- hGetLine inh 
        hPutStrLn outh (map toUpper inpStr) 
        mainloop inh outh 

Chúng tôi chủ yếu xem xét thế giới bên ngoài là stream.

5

Nếu bạn sử dụng tail recursion, bạn có hiệu quả lặp lại, như vòng lặp for/while. Vì vậy, tôi đoán bạn có thể có một vòng lặp vô hạn mà không nhận được tràn ngăn xếp.

Đối với câu hỏi của bạn: "là vòng lặp vô hạn, bộ nhớ sai cho lập trình hàm?" có lẽ đây sẽ giúp: - While or Tail Recursion in F#, what to use when?

0

Hầu hết nếu không phải tất cả việc sử dụng "vòng lặp vô hạn" trong lập trình hàm đều có thể được mô hình hóa theo co-recursion. Các câu trả lời khác cho đến nay đã chỉ ra đệ quy chung, nhưng việc sử dụng đệ quy không hạn chế được cho là một cách tiếp cận nghèo nàn vì nó có thể dẫn đến mã có cấu trúc kém.

Phần lớn mã trong chương trình thuần túy cần được viết trong tổng tập hợp con, tức là sử dụng các mẫu như đệ quy cấu trúc hoặc đồng đệ quy (đảm bảo chấm dứt và tiến trình) thay vì quay trở lại đệ quy chung. Hy vọng rằng, các phiên bản tương lai của GHC sẽ bao gồm hỗ trợ trực tiếp để phát hiện một số tập hợp con của Haskell và phát ra các cảnh báo cho mã không thể được chứng minh là chấm dứt hoặc tiến triển.

Các vấn đề liên quan