En primer lugar, puede ser útil tener en cuenta que ninguna de las cosas que ha definido es una función - eagerFunc
y theValue
son valores de tipo int
y lazyFunc
es un valor de tipo Lazy<int>
. Dada
let lazyTwo = lazy (1 + 1)
y
let eagerTwo = 1 + 1
la expresión 1 + 1
se no ser evaluados más de una vez, no importa cuántas veces se utiliza eagerTwo
. La diferencia es que 1 + 1
serán evaluados exactamente una vez cuando definireagerTwo
, pero serán evaluados como máximo una vez cuando lazyTwo
es utiliza (se evaluará la primera vez que se accede a la propiedad Value
, y luego almacenado en caché para que otros usos de Value
no necesiten recalcularlo). Si lazyTwo
's Value
nunca se accede, entonces su cuerpo 1 + 1
será nunca se evaluará.
Normalmente, no verá mucho beneficio al usar valores diferidos en un lenguaje estricto como F #. Agregan una pequeña cantidad de sobrecarga ya que para acceder a la propiedad Value
es necesario verificar si el valor ya se ha calculado. Podrían ahorrarte un poco de cálculo si tienes algo como let lazyValue = lazy someVeryExpensiveCalculationThatMightNotBeNeeded()
, ya que el cálculo costoso solo tendrá lugar si el valor se usa realmente. También pueden hacer que terminen algunos algoritmos que de otra forma no lo harían, pero este no es un problema importante en F #. Por ejemplo:
// throws an exception if x = 0.0
let eagerDivision x =
let oneOverX = 1.0/x
if x = 0.0 then
printfn "Tried to divide by zero" // too late, this line is never reached
else
printfn "One over x is: %f" oneOverX
// succeeds even if x = 0.0, since the quotient is lazily evaluated
let lazyDivision x =
let oneOverX = lazy (1.0/x)
if x = 0.0 then
printfn "Tried to divide by zero"
else
printfn "One over x is: %f" oneOverX.Value
¿Qué versión de F # es esto? Tengo una secuencia que está actuando perezosamente, pero no fue abiertamente creada de esa manera. Estoy tratando de forzarlo a que se complete. – octopusgrabbus