Me encontré con la siguiente definición cuando trato de aprender Haskell usando un proyecto real para conducirlo. No entiendo lo que significa el signo de exclamación frente a cada argumento y mis libros no parecen mencionarlo.
data MidiMessage = MidiMessage !Int !MidiMessage
haskell
syntax
lazy-evaluation
David
fuente
fuente
Respuestas:
Es una declaración de rigor. Básicamente, significa que debe evaluarse a lo que se llama "forma normal de cabeza débil" cuando se crea el valor de la estructura de datos. Veamos un ejemplo, para que podamos ver lo que esto significa:
La función
f
anterior, cuando se evalúa, devolverá un "thunk": es decir, el código a ejecutar para calcular su valor. En ese momento, un Foo aún no existe, solo el código.Pero en algún momento alguien puede intentar mirar dentro de él, probablemente a través de una coincidencia de patrones:
Esto va a ejecutar suficiente código para hacer lo que necesita, y nada más. Por lo tanto, creará un Foo con cuatro parámetros (porque no puede mirar dentro sin que exista). El primero, ya que lo estamos probando, necesitamos evaluar todo el camino para
4
que nos demos cuenta de que no coincide.El segundo no necesita ser evaluado, porque no lo estamos probando. Por lo tanto, en lugar de
6
ser almacenado en esa ubicación de memoria, sólo tendremos que almacenar el código para una posible evaluación posterior,(3+3)
. Eso se convertirá en un 6 solo si alguien lo mira.Sin embargo, el tercer parámetro tiene un
!
frente, por lo que se evalúa estrictamente:(4+4)
se ejecuta y8
se almacena en esa ubicación de memoria.El cuarto parámetro también se evalúa estrictamente. Pero aquí es donde se vuelve un poco complicado: estamos evaluando no completamente, sino solo con una forma de cabeza normal débil. Esto significa que descubrimos si es
Nothing
o noJust
, y lo almacenamos, pero no vamos más allá. Eso significa que no almacenamosJust 10
pero en realidadJust (5+5)
, dejamos el thunk adentro sin evaluar. Es importante saberlo, aunque creo que todas las implicaciones de esto van más allá del alcance de esta pregunta.Puede anotar argumentos de función de la misma manera, si habilita la
BangPatterns
extensión de idioma:f (1+1) (2+2)
devolverá el golpe(1+1)*4
.fuente
seq
.Una manera simple de ver la diferencia entre argumentos de constructor estrictos y no estrictos es cómo se comportan cuando no están definidos. Dado
Dado que el argumento no estricto no es evaluado por
second
, pasarundefined
no causa un problema:Pero el argumento estricto no puede ser
undefined
, incluso si no usamos el valor:fuente
!
tiene el símbolo, en lugar de profundizar en los detalles de implementación internos.Creo que es una anotación estricta.
Haskell es un lenguaje funcional puro y vago , pero a veces la sobrecarga de la pereza puede ser demasiado o un desperdicio. Entonces, para lidiar con eso, puede pedirle al compilador que evalúe completamente los argumentos de una función en lugar de analizar los thunks.
Hay más información en esta página: rendimiento / rigidez .
fuente
map Just [1,2,3]
para obtener [Solo 1, Solo 2, Solo 3]) y así sucesivamente. Me resulta útil pensar en la capacidad de combinar patrones con ellos, así como en una instalación completamente no relacionada.