2010-05-07 23 views
26

¿Alguien puede explicar la diferencia en Haskell entre los operadores ($) y ($!) (signo de dólar frente a signo de dólar signo de exclamación)?

no he visto el uso de $! en cualquier lugar hasta ahora, pero mientras se navega a través de la Haskell reference, me di cuenta de su existencia y que tiene la misma definición exacta como $. Al intentar algunas afirmaciones simples en un intérprete de Haskell (GHCi), no pude encontrar ninguna diferencia, ni pude encontrar ninguna referencia al operador en los tutoriales enumerados arriba al buscar haskell tutorial.

Entonces, solo por curiosidad, ¿cuál es la diferencia, si es que lo hace?

+1

HIYF: http://www.haskell.org/hoogle/?q=%28%24!%29&format=sherlock – jberryman

+0

Vea también http://stackoverflow.com/questions/940382/haskell-difference-between- dot-and-dollar-sign –

Respuesta

42

($!) es una aplicación de función estricta. Es decir, evalúa el argumento antes de evaluar la función.

Esto es contrario a la aplicación de función diferida normal en Haskell, p. f x o f $ x, que primero comienzan a evaluar la función f, y solo calculan el argumento x si es necesario.

Por ejemplo succ (1 + 2) retrasará la adición 1 + 2 creando un procesador y comenzará a evaluar succ primero. Solo si se necesita el argumento para succ, se evaluará 1 + 2.

Sin embargo, si está seguro de que el argumento para una función siempre será necesario, puede usar ($!), que primero evaluará el argumento para la forma normal de cabeza débil, y luego ingresará la función. De esta forma, no creas una gran pila de thunks y esto puede ser más eficiente. En este ejemplo, succ $! 1 + 2 primero calcularía 3 y luego ingresaría la función succ.

Tenga en cuenta que no siempre es seguro simplemente reemplazar la aplicación de función normal con la aplicación de función estricta. Por ejemplo:

ghci> const 1 (error "noo!") 
1 
ghci> const 1 $! (error "noo!") 
*** Exception: noo! 
+4

El último ejemplo es más sobre el efecto secundario de 'error'. La semántica funcional nunca debería verse afectada por explosiones (lo mismo para 'par' y' seq'). Poner flequillo a veces puede aumentar la velocidad/memoria y, a veces, disminuir. Y en algunos casos especiales, puede llevar a cálculos interminables 'const 1 $! (último [1 ..]) '. – ony

+8

Bueno, la impresión del mensaje es un efecto secundario, pero el punto es que 'error' es ⊥ (abajo). Al igual que un cálculo interminable es ⊥. Si evalúa ⊥ usando un 'seq', la semántica de su programa cambia. Esta es la razón por la que debe tener cuidado con cosas como 'seq' y' ($!) ', Puede aumentar (o disminuir) la eficiencia de su programa, pero también podría hacer que se bloquee donde normalmente no debería tener. –

7

Véase la función seq, lo que obliga a la evaluación de un valor. $! se define en términos de seq.

This es una publicación de blog que muestra algunos matices de su uso.

+0

¡Ah, estúpido! Lo dice zvon también en la descripción de '$!', Pero por alguna razón el signo igual nunca tocó la campana ... Gracias por el enlace al blog. –

+1

'f $! x = x '' seq'' f x' http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Prelude.html #% 24% 21 –

+0

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la opinión] (/ reseña/mensajes de baja calidad/17886026) – guradio

Cuestiones relacionadas