2012-03-04 11 views
21

Aquí un extracto de la documentación evaluar: (cf. http://hackage.haskell.org/packages/archive/base/4.5.0.0/doc/html/Control-Exception-Base.html#v:evaluate)"evaluar" función

evaluate x 

no es lo mismo que

return $! x 

Una definición correcta es

evaluate x = (return $! x) >>= return 

No entiendo la diferencia semántica entre estas dos definiciones ... ¿Hay alguien que pueda ayudarme? ¡Gracias de antemano!

+4

¿Esto no infringe realmente las leyes de mónadas? – leftaroundabout

+2

@leftaroundabout No, no es así. Ambos se comportan exactamente igual si se ejecutan, pero si 'seq' las expresiones,' devuelve $! x' tiene un 'seq' más externo, mientras que' (return $! x) >> = return' tiene un '(>> =)' outermost. –

+4

@leftaroundabout: No, porque ⊥ se ignora a los efectos de las leyes. Las mónadas estándar como 'Reader' se comportan de la misma manera. (No me creo el argumento de Daniel Fischer (que he escuchado antes de otros), porque "comportarse exactamente igual si se ejecuta" no es realmente un concepto bien definido.) – ehird

Respuesta

19

ref rápida:

El tipo de evaluate es:

evaluate :: a -> IO a 

seq tiene el tipo a -> b -> b. Primero evalúa el primer argumento, luego devuelve el segundo argumento.

Evaluar sigue estas tres reglas:

evaluate x `seq` y ==> y 
evaluate x `catch` f ==> (return $! x) `catch` f 
evaluate x >>= f  ==> (return $! x) >>= f 

La diferencia entre el return $! x y (return $! x) >>= return se hace evidente con esta expresión:

evaluate undefined `seq` 42 

por la primera regla, que debe evaluar a 42

Con el return $! x definición, la expresión anterior causaría una excepción indefinida. Esto tiene el valor ⊥, que no es igual a 42.

Con la definición (return $! x) >>= return, que es igual a 42.

Básicamente, la forma return $! x es estricta cuando se calcula el valor IO. La otra forma solo es estricta cuando se ejecuta el valor IO y se usa el valor (usando >>=).

Ver this mailing list thread para más detalles.

+0

¿Por qué '(return $! Undefined) >> = return' diferente de' return $! undefined'?Supongo que el primero introduce una capa adicional de direccionamiento indirecto que impide que 'undefined' se evalúe en' ((return $! Undefined) >> = return) \ 'seq \' 42'. – mucaho

Cuestiones relacionadas