2010-01-24 35 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