2010-11-09 15 views
5

Así que tengo un poco de código *, que cuando toma tres puntos, se supone que devuelve una dirección. He escrito esta solución, pero cada vez que intento ejecutarla, hace que el GHCi se congele, así que me pregunto qué estoy haciendo mal. Aquí está el código:Strange Haskell/GHCi issue

--chapter 3 question 9 
data Point x y = Point x y deriving (Eq, Show) 
data Vector x y = Vector x y deriving (Eq, Show) 

sub (Point x y) (Point a b) = (Vector (x-a) (y-b)) 
dot (Vector x y) (Vector a b) = (x*a)+(y*b) 
perp (Vector x y) = (Vector (-y) x) 
mag (Vector x y) = sqrt (dot v v) where v = (Vector x y) 

data Direction = LeftTurn | RightTurn | Straight | Reverse | Stop | Undefined 
    deriving (Eq, Show) 
getDirection (Point a b) (Point c d) (Point e f) 
    | a/=c && b/=d && c==e && d==f = Stop 
    | a==c && b==d || c==e && d==f || e==a && f==b = Undefined 
    | d > 0 = LeftTurn 
    | d < 0 = RightTurn 
    | otherwise = Straight 
    where d = dot (sub p1 p0) (perp (sub p2 p1)) 
      where p0 = (Point a b) 
       p1 = (Point c d) 
       p2 = (Point e f) 

No hay recursividad que puedo ver, así que no entiendo por qué se comportan de esta manera. Hasta ahora, el compilador Haskell ha sido muy elocuente sobre decirme cuando estoy haciendo algo tonto, pero esto compila muy bien.

* Esta es la Pregunta 9 del Capítulo 3 de "Real World Haskell" en caso de que se lo esté preguntando.

+1

¿Estás seguro de que tus declaraciones de datos significan lo que piensas que significan? Por el momento, podría tener un punto [cadena] (punto, vector), solo para nombrar un tipo de punto tonto. Según su uso, ¿no sería mejor declarar los datos Point = Point Int Int derivando (Eq, Show)? – Boris

Respuesta

7

Has vinculado el nombre dos veces. Primero en el patrón Point c d que en la cláusula where.

Por lo tanto, si usted está tratando de acceder al d obligado por el patrón, en realidad estás en referencia a la d de la cláusula where de forma recursiva.

+0

Gracias, nunca lo hubiera averiguado. – horatius83

+5

Si ejecuta GHCi con -Wall, recibirá una advertencia al respecto. –

+2

O mejor aún, agregue la línea ": set -Wall" a su archivo ~/.ghci. –