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