I´ve written a function in Haskell that takes three points in the plane, and checks if they´re on a straight line, or make a right or left turn.
Here´s the code:
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
I´ve tested collinear1, angle, turnAtP in GHCi, and they all terminate immediately.
detDirection, however, keeps running forever.
Can someone tell me where the problem here is?
In Haskell, let is a recursive binding, that is, you can refer to variables declared in the let expression in the defining expressions of the other variables. So, when you write
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
the x1, x2, y1, and y2 on the first line do not refer to the function arguments but to the same names declared later on in the let expression. Just change the two Point lines to bind some different variables, like
        (Point (x3, y3))    = turnAtP a b angleAbX
        (Point (x4, y4))    = turnAtP a c angleAbX
and modify your later computation accordingly, and your infinite looping will go away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With