2009-11-22 13 views
16

Una pregunta rápida que me ha estado molestando últimamente. ¿Realiza Haskell toda la prueba de equivalencia en una función que devuelve un valor booleano, incluso si uno devuelve un valor falso?Cortocircuito (&&) en Haskell

Por ejemplo

f a b = ((a+b) == 2) && ((a*b) == 2) 

Si la primera prueba devuelve falso, va a realizar la segunda prueba después de la &&? ¿O es Haskell lo suficientemente flojo como para no hacerlo y seguir adelante?

Respuesta

18

Debe cortocircuitarse como en otros idiomas. Se define así en el Preludio:

(&&)     :: Bool -> Bool -> Bool 
True && x    = x 
False && _    = False 

Así que si el primer parámetro es el segundo Falso nunca necesita ser evaluado.

+0

¿Es esto también lo mismo en el caso de la lista de comprensiones? –

+0

'Cortocircuito' no se habla correctamente. Simplemente no se sabe si se evalúan los valores, ya que no hay manera de probarlo sin efectos secundarios, pero es poco probable que lo hagan a menos que sea necesario. – Dario

+0

Creo que es lo mismo que C++: el lenguaje dice que el lado derecho no se evalúa. Pero, por supuesto, si el compilador puede decir que no hay efectos secundarios, puede evaluarlo de todos modos, y algunos compiladores de C++ lo hacen, ya que las ramas condicionales son costosas. –

1

Evaluación diferida significa que nada se evalúa hasta que realmente se necesita.

5

Como dijo Martin, los idiomas con evaluación diferida nunca evalúan nada que no sea necesario de inmediato. En un lenguaje lento como Haskell, obtienes un cortocircuito gratis. En la mayoría de los idiomas, || y & & y operadores similares deben construirse especialmente en el idioma para que puedan realizar una evaluación de cortocircuito. Sin embargo, en Haskell, la evaluación perezosa hace que esto sea innecesario. Se podría definir una función que incluso usted mismo cortocircuitos:

scircuit fb sb = if fb then fb else sb

Esta función se comportan igual que el 'o' operador lógico. Aquí es cómo || se define en Haskell:

True || _ = True 
False || x = x 

Entonces, para darle la respuesta específica a su pregunta, no. Si el lado izquierdo de || es cierto, el lado derecho nunca se evalúa. Puede poner dos y dos juntos para los otros operadores que 'cortocircuiten'.

Cuestiones relacionadas