2011-04-10 5 views
11

En el wiki sección Haskell Performance Resource, se da la recomendación no se explica más a¿Cuál es la semántica de "retornos estrictos"?

  • Use vuelve estrictas (return $! ...) a menos que sea absolutamente necesario perezosos.

¿Por qué es que una buena cosa que hacer? ¿Cuándo exactamente es el ... -expression (Whnf-) forzado?

Dada la "identidad de izquierda" mónada-ley y la definición

f $! x = x `seq` f x 

puedo volver a escribir (en do -notation`):

do x' <- return $! x 
    f x' 

a

do x' <- x `seq` return x 
    f x' 

Pero parece que no puedo obtener

do f $! x 

PS: Si el BangPatterns -Ampliación está disponible, es

do !x' <- return x 
    f x' 

semánticamente lo mismo que la primera do-expresión dada anteriormente?

Respuesta

5

Hay una razón por la que no se puede obtener de

do x' <- x `seq` return x 
    f x' 

a

f $! x 

Es porque no son lo mismo. Simplemente ampliar la notación do:

(x `seq` return x) >>= (\ x' -> f x') 

El seq solamente se evaluará si el (>>=) es estricta en su primer argumento. Eso no es necesariamente cierto.

+0

veo ... ¿Pero qué dice esto acerca de la utilidad de 'retorno $! ... '? ¿Tiene sentido solo para mónadas estrictas? – hvr

+0

@hvr: si la mónada es estricta en su tipo de devolución, entonces sí. La construcción es especialmente útil para mónadas en las que generalmente se desea evaluar un efecto secundario de la mónada y no la mónada en sí misma. – fuz

+0

Tiene sentido que lo último en un bloque do sea 'return $! ... 'porque el valor de retorno de una función (llamada) siempre se evalúa. Es decir, en '... >> = \ x -> devuelve $! ...', una vez que se llama esa expresión lambda, va a evaluar la aplicación' ($!) '. – augustss

1

Para IO también existe el útil Control.Exception.evaluate:

Fuerzas su argumento de que ser evaluado para forma normal débil cabeza cuando se ejecuta la acción IO resultante. Es se puede utilizar para ordenar la evaluación con con respecto a otras operaciones de E/S; sus semántica están dadas por

evaluate :: a -> IO a 
evaluate x = (return $! x) >>= return 
Cuestiones relacionadas