2012-01-31 11 views
13

Para mí, un Cierre es una función (anidada?) Con datos coubicados.Cierres (en Haskell)

Cuando escribe software en Haskell y lo revisa después, con frecuencia encuentra cierres que ha creado involuntariamente.

No entiendo bien esto por mí mismo. ¿En qué situaciones intencionalmente querría programar cierres? Después de todo, en todos los ejemplos encuentro que la cantidad de datos coubicados es trivial/pequeña y por lo tanto no me parece que en la práctica justifique su creación (intencional). ¿Hay algún módulo de Haskell que me apoye en la creación intencional de cierres y p. almacenándolos en un mapa?

+4

Pregunta interesante ... ¿Qué quiere decir exactamente por cierres creados involuntariamente? –

+0

@Jonathan Sterling principalmente cuando crea funciones anidadas. Por lo general, cumplen los criterios para llamarse "cierre" –

+0

, ya que dflemstr señala que está creando "cierres" todo el tiempo. Esto ni siquiera es un concepto que vale la pena tener un nombre en Haskell. ¿Entiende el currying y la aplicación parcial, y cómo la firma de tipo 'Int -> Int -> Int 'es equivalente a' Int -> (Int -> Int)'? – jberryman

Respuesta

25

En Haskell, las funciones son una parte esencial del lenguaje, en gran parte porque Haskell se basa en el Lambda Calculus.

En el cálculo de Lambda, hay funciones que tienen "variables libres", lo que significa que utilizan variables que no se pasaron como parámetros directos a ellas. Las funciones con variables libres son lo que usted llamaría "cierres" en este caso.

Dado que las funciones con variables libres son tan comunes en LC, también forman parte integral del lenguaje Haskell. Por ejemplo, al escribir esto:

f a b c = a * b + c 

... también podría estar escribiendo esto, con exactamente el mismo resultado:

f a b = \ c -> a * b + c 

... o incluso:

f a b = let product = a * b in \ c -> product + c 

... más cambios equivalentes:

f a = \ b -> let product = a * b in \ c -> product + c 

Esto se debe a que Haskell crea esencialmente funciones con las variables libres en todas partes, y por lo tanto, los cierres se crean todo el tiempo. Algunos de estos pueden ser optimizados por el compilador, pero es seguro suponer que se utilizarán más cierres de los que nunca podrá descubrir por su cuenta.

Por lo tanto, no intente localizar cierres; no son nada especial en Haskell y se usan todo el tiempo.

+0

Entendido. Todavía lo que no tengo claro es: ¿puedo en Haskell (a) crear cierres intencionalmente y (b) almacenarlos en un mapa y (c) serializarlos sin complicaciones como lo podría hacer en Erlang con term_to_binary()? –

+0

@JFritsch, puede almacenar funciones fácilmente en un mapa y sobre "crear cierres intencionalmente"; Haskell no distingue entre cierres y funciones normales, por lo que es tan fácil como simplemente almacenar funciones normales en un mapa. Sin embargo, es muy difícil serializar funciones, y si bien hay un soporte experimental en GHC para ello, todavía no existe una manera confiable de hacerlo. Recuerde que las variables pueden hacer referencia a, p. manejadores de archivos, y si un cierre se basa en dicha variable, realmente no se puede convertir en un flujo de bits. – dflemstr

+0

Entonces, ¿no podré serializar mi mapa resultante con Data.Binary? –

3

Normalmente, si necesito calcular previamente tablas o algo para una función, o hay una función que requiere mucha información, sí, eso se hará como cierre. Por ejemplo, en mi tarea de IA el otro día, escribí algo que aprendí de muchas muestras y luego saqué una función (Point -> Bool), pero esa función tenía que depender de una gran cantidad de datos que había acumulado del proceso de aprendizaje .

+0

¿Pueden por favor explicar eso un poco más o publicar un código de muestra? –