Reputation: 51
The output from below is 15,9,9 however I want 15,9,21 I want to preserve a lazy version so I can put in a new function version in a composed function.
open System
let mutable add2 = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable co = add2 >> mult3
let mutable com = lazy( add2 >> mult3)
let mutable com2 = com
add2<- fun x-> x
co 3|> printfn "%A"
com.Force() 3|> printfn "%A"
add2<- fun x-> x+4
com2.Force() 3|> printfn "%A"
Upvotes: 1
Views: 176
Reputation: 243096
I don't think you need lazy values here - lazy value is evaluated once when needed, but its value does not change afterwards. In your case, you need Force
to re-evaluate the value in case some dependencies have changed. You can define something like this:
type Delayed<'T> =
| Delayed of (unit -> 'T)
member x.Force() = let (Delayed f) = x in f()
let delay f = Delayed f
This represents a delayed value (really, just a function) with Force
method that will evaluate it each time it is accessed. If you rewrite your code using delay
, it behaves as you wanted:
let mutable add2 = fun x-> x+2
let mutable mult3 = fun x-> x*3
let mutable com = delay(fun () -> add2 >> mult3)
let mutable com2 = com
add2 <- fun x -> x
com.Force() 3 |> printfn "%A"
add2 <- fun x -> x + 4
com2.Force() 3 |> printfn "%A"
Unlike lazy, this does not do any caching, so calling Force
twice will just do the whole thing twice. You could add some caching by tracking a dependency graph of the computation, but it gets more complicated.
Upvotes: 1