2010-01-24 61 views
5

我在Haskell中編寫了一個函數,它在飛機上需要三個點, 並檢查它們是否在一條直線上,或者右轉或左轉。Haskell函數不終止

Here's代碼:

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 

從來就在GHCI測試collinear1angleturnAtP,他們都立即終止。然而, detDirection會一直運行。

有人能告訴我這裏的問題在哪裏嗎?

+0

試圖逐行逐行通過它? – 2010-01-24 23:01:00

+5

打開GHCi中的':set-Wall'的警告,你會清楚地知道你做錯了什麼。 – ephemient 2010-01-25 05:11:37

回答

15

在Haskell中,let是一個遞歸綁定,也就是說,您可以引用其他變量的定義表達式中let表達式中聲明的變量。所以,當你寫

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 

x1x2y1,並y2在第一行不涉及函數的參數,但在let表達式聲明以後相同的名稱。只要改變這兩個Point線綁定一些不同的變量,如

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

,並相應修改後的計算,你的無限循環將持續下去。

+1

非常感謝, 我不敢相信我實際上沒有注意到我的函數參數的影子..... 下次我會使用GHCi中的警告! – Ben 2010-01-25 18:10:53