curried - ¿Cuándo se evalúan las llamadas a la función F#? perezoso o inmediatamente?
currying javascript (4)
Funciones al curry en f #. Obtengo el bit donde pasar un subconjunto de parámetros produce una función con ajustes preestablecidos. Me pregunto si pasar todos los parámetros es diferente. Por ejemplo:
let addTwo x y = x + y
let incr a = addTwo 1
let added = addTwo 2 2
incr
es una función que toma un argumento. ¿Se added
un int o una función? Puedo imaginar una implementación donde "agregado" se evalúa perezosamente solo en uso (como el Gato de Schroedinger''s al abrir la caja). ¿Hay alguna garantía de cuándo se realiza la adición?
incr es una función que toma un argumento. ¿Se agrega un int o una función?
added
, en este caso, es un enlace con nombre que se evalúa como un int. No es una función.
Puedo imaginar una implementación donde "agregado" se evalúa perezosamente solo en uso (como el Gato de Schroedinger''s al abrir la caja). ¿Hay alguna garantía de cuándo se realiza la adición?
La adición se realizará inmediatamente cuando se genere la unión. No hay pereza involucrada.
Como lo explica TeaDrivenDev , puede cambiar added
para que sea una función enlazada en lugar de un valor enlazado agregando un parámetro, que puede ser unit
:
let added () = addTwo 2 2
En este caso, será una función, por lo que la adición no se realizará hasta que la llame:
let result = added () // Call the function, bind output to result
F # es un lenguaje evaluado con entusiasmo , por lo que una expresión como addTwo 2 2
evaluará inmediatamente a un valor del tipo int
.
Haskell, por el contrario, se evalúa perezosamente. Una expresión como addTwo 2 2
no se evaluará hasta que se necesite el valor. Sin embargo, el tipo de expresión todavía sería un solo entero. Aun así, tal expresión es, a pesar de su pereza, no considerada como una función; en Haskell, tal expresión no evaluada se llama thunk . Eso básicamente significa "una expresión arbitrariamente compleja que aún no se ha evaluado".
No. Pero un poco de sí. Pero en realidad, no.
Puedes construir un lenguaje funcional puro que solo tiene funciones y nada más. El cálculo lambda es un álgebra completa, por lo que la teoría está ahí. En este modelo, el added
puede considerarse una función sin parámetros (a diferencia de, por ejemplo, random()
, donde hay un parámetro de tipo unidad).
Pero F # es diferente. Dado que es una combinación bastante pragmática de programación imperativa y funcional, el resultado no es una función [1]. En su lugar, es un valor, al igual que un local en C #. Esto no es un detalle de implementación, en realidad es parte de la especificación F #. Esto tiene desventajas: significa que es posible tener una definición ambigua, donde una definición podría ser un valor o una definición de función (14.6.1).
[1] - Aunque en un programa funcional puro, no se puede notar la diferencia, es lo mismo que hacer una sustitución de la función con un valor almacenado en caché, lo cual es perfectamente legal.
added
no es una función; es solo un valor que se calcula y se vincula al nombre en el lugar. Una función siempre necesita al menos un parámetro; si no hay nada útil para pasar, ese sería el valor unit
()
:
let added () = addTwo 2 2