2010-01-24 20 views
5

He escrito una función en Haskell que toma tres puntos en el avión, y comprueba si están en línea recta, o gire a la derecha o izquierda.La función de Haskell no termina

tope aquí tienes el código:

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 

he probado collinear1, angle, turnAtP en GHCi, y todos ellos terminará inmediatamente. detDirection, sin embargo, sigue funcionando para siempre.

¿Puede alguien decirme dónde está el problema aquí?

+0

¿Intenté recorrerlo línea por línea? –

+5

Activa las advertencias (': set -Wall' en GHCi) y obtendrás algunas indicaciones claras de lo que hiciste mal. – ephemient

Respuesta

15

En Haskell, let es un enlace recursivo, es decir, puede hacer referencia a las variables declaradas en la expresión let en las expresiones de definición de las otras variables. Por lo tanto, cuando se escribe

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 

la x1, x2, y1, y y2 en la primera línea no se refieren a los argumentos de la función, pero con los mismos nombres declarados más adelante en la expresión let. Sólo cambia las dos Point líneas para unir algunas variables diferentes, como

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

y modificar su cómputo más adelante en consecuencia, y su ciclo infinito va a desaparecer.

+1

Muchas gracias, No puedo creer que realmente haya sombreado los argumentos de mi función sin darme cuenta ..... ¡La próxima vez usaré las advertencias en GHCi! – Ben

Cuestiones relacionadas