Haskell Hero
Haskell Hero es un manual interactivo del lenguaje Haskell para principiantes.
|
Evaluación IIDesde las instrucciones hasta el resultadoEjemplo
Evaluad paso a paso la expresión tresVeces x = x + x + x
¿Cómo empezar? ¿Evaluar primero La respuesta es: Depende de la estrategia de evaluación elegida.
Sin definirlo explícitamente de otra manera, Haskell evalúa de manera perezosa. Evaluación normal
La estrategia de evaluación normal significa la evaluación de afuera hacia adentro (en otras palabras, la evaluación mediante paso por nombre). En concreto, si la expresión está en forma
En breve: Sin mirar a la evaluación de parámetros aplicamos la función
La expresión de ejemplo se evaluaría según la estrategia de evaluación normal de manera siguiente:
tresVeces (5 + 2) ~> (5 + 2) + (5 + 2) + (5 + 2) ~> 7 + (5 + 2) + (5 + 2) ~> 7 + 7 + (5 + 2) ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 Evaluación esctrictaLa estrategia de evaluación estricta significa la evaluación de adentro hacia afuera (en otras palabras, la evaluación mediante paso por valor). En conreto, primero evaluamos parámetros a expresiones irreducibles y solo después aplicamos la función.
La expresión de ejemplo se evaluaría según la estrategia de evaluación estricta de manera siguiente:
tresVeces (5 + 2) ~> tresVeces 7 ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 Evaluación perezosaLa estrageia de evaluación perezosa funciona casi de misma manera como la evaluación normal.Sin embargo, a diferencia de la evaluación normal, cuando evaluamos de manera perezosa, recordamos los resultados de evaluaciones de expresiones individuales. Antes de la evaluación primero miramos si ya no hemos evaluado tal expresión. Si es así, utilizamos el resultado de la evaluación anterior.
La expresión de ejemplo se evaluaría según la estrategia de evaluación perezosa de manera siguiente:
tresVeces (5 + 2) ~> (5 + 2) + (5 + 2) + (5 + 2) ~> 7 + 7 + 7 ~> 14 + 7 ~> 21 ¿Por qué estrategias diferentes?Parece que la estrategia estricta es la más efectiva. No hay que controlar si la expresión ya se ha evaluado y es la estrategia más rápida. Entonces, ¿por qué necesitamos otras dos estrategias?
Por ejemplo evaluemos la expresión take 3 [1..] ~> take 3 ( 1: [2..] ) ~> take 3 ( 1: 2: [3..] ) ~> take 3 ( 1: 2: 3: [4..] ) ~> take 3 ( 1: 2: 3: 4: [5..] ) ~> take 3 ( 1: 2: 3: 4: 5: [6..] ) ~> take 3 ( 1: 2: 3: 4: 5: 6: [7..] ) ~> ... La evaluación no terminaría nunca porque la evaluación estricta requiere que se simplifiquen todos los parámetros, lo que no se puede hacer evaluando una lista infinita. Evaluando según la estrategia normal llegamos a esto: take 3 [1..] ~> take 3 ( 1: [2..] ) ~> 1 : take 2 [2..] ~> 1 : take 2 ( 2: [3..] ) ~> 1 : 2 : take 1 [3..] ~> 1 : 2 : take 1 ( 3: [4..] ) ~> 1 : 2 : 3 : take 0 [4..] ~> 1 : 2 : 3 : [] Otro ejemplo podría ser la evaluación de expresiones con valores booleanos. False && _ = False True && x = x ------------------------ False && ( and [True, True..] ) ~> False Si evaluáramos de manera estricta, la evaluación no terminaría nunca. Si evaluamos de manera normal/perezosa, llegamos hasta el resultado después de un paso. Usamos la evaluación perezosa para prevenir la evaluación múltiple de las mismas expresiones. |