Haskell函数不会终止

时间:2010-01-24 22:51:54

标签: haskell terminate

我在Haskell中写了一个函数,它在飞机上占了三个点, 并检查它们是否在一条直线上,或向右或向左转。

这是代码:

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

detDirection a@(Point (x1, y1)) b@(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会一直运行。

有人可以告诉我这里的问题在哪里吗?

1 个答案:

答案 0 :(得分: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

第一行中的x1x2y1y2不是引用函数参数,而是引用稍后在{\ n}中声明的相同名称{1}}表达。只需更改两个let行即可绑定一些不同的变量,例如

Point

并相应地修改你的后续计算,你的无限循环就会消失。