2010-01-24 35 views
5

Tôi đã viết một chức năng trong Haskell mất ba điểm trên mặt phẳng, và kiểm tra xem chúng có đang chạy thẳng hay rẽ phải hay trái.Chức năng Haskell không chấm dứt

Here's mã:

detDirection :: Point -> Point -> Point -> Direction 

detDirection [email protected](Point (x1, y1)) [email protected](Point (x2, y2)) c 

= if (collinear1 a b c) 
    then Straight 
    else let 
      ab     = Vector [x2 - x1, y2 - y1] 
      angleAbX   = angle ab (Vector [1, 0]) 
      (Point (x1, y1)) = turnAtP a b angleAbX 
      (Point (x2, y2)) = turnAtP a c angleAbX 

      in if (y1 > y2) 
       then Right 
       else Left 

Tôi đã thử nghiệm collinear1, angle, turnAtP trong GHCi, và tất cả đều chấm dứt ngay lập tức. Tuy nhiên, detDirection vẫn tiếp tục chạy mãi mãi.

Ai đó có thể cho tôi biết sự cố ở đây là ở đâu?

+0

Đã thử bước qua từng dòng một? –

+5

Bật cảnh báo trên (': set -Wall' trong GHCi) và bạn sẽ nhận được một số chỉ dẫn rõ ràng về những gì bạn đã làm sai. – ephemient

Trả lời

15

Trong Haskell, let là một liên kết đệ quy, nghĩa là bạn có thể tham chiếu đến các biến được khai báo trong biểu thức let trong biểu thức xác định của các biến khác. Vì vậy, khi bạn viết

let 
     ab     = Vector [x2 - x1, y2 - y1] 
     angleAbX   = angle ab (Vector [1, 0]) 
     (Point (x1, y1)) = turnAtP a b angleAbX 
     (Point (x2, y2)) = turnAtP a c angleAbX 

các x1, x2, y1y2 trên dòng đầu tiên không đề cập đến các đối số chức năng nhưng với tên cùng tuyên bố sau này trong biểu thức let. Chỉ cần thay đổi hai Point dòng để ràng buộc một số biến khác nhau, như

 (Point (x3, y3)) = turnAtP a b angleAbX 
     (Point (x4, y4)) = turnAtP a c angleAbX 

và sửa đổi tính toán sau cho phù hợp, và vòng lặp vô hạn của bạn sẽ biến mất.

+1

Cảm ơn bạn rất nhiều, Tôi không thể tin rằng tôi thực sự đã che giấu các đối số chức năng của mình mà không nhận thấy ..... Lần tới tôi sẽ sử dụng các cảnh báo trong GHCi! – Ben

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