Reputation: 3292
I have a console app that has an example function:
let aFxUsedFromTheEntryPoint () =
let aHelperFx (cThing) (iThing) (qThing) =
Unchecked.defaultof<Quote>
let c =
thisFx() //this line reads in and process lots of data; takes some time
let i =
thatFx() //this line also reads in and processes lots of data; takes some time
aList
|> List.map (fun q -> aHelperFx c i q)
How are the c
and i
variables used in the function? Are they read in once before last two lines and just used repeatedly, for however long aList
is? Or are they executed once for every q
in `aList'?
If the latter, is there a better way to go about writing a function like this? Can I somehow write the function so that c
and i
are run only once, yet passed however many times it's necessary in aList
?
Upvotes: 2
Views: 80
Reputation: 26184
The most obvious solution is to move them out of the function body:
let c = thisFx() //this line reads in and process lots of data; takes some time
let i = thatFx() //this line also reads in and processes lots of data; takes some time
let aFxUsedFromTheEntryPoint () =
let aHelperFx (cThing) (iThing) (qThing) = Unchecked.defaultof<Quote>
aList |> List.map (fun q -> aHelperFx c i q)
Typically if your function is declared inside a module, then those two let bindings can be declared at the same level as the function, in this case at the module level.
This is the first thing I will consider. Now if you want them to be called the first time the aFxUsedFromTheEntryPoint
function is called then you can use other techniques like memoization or the lazy value as explained in the other answer, but note that the first call to the function will be slower than the subsequent calls.
Upvotes: 2
Reputation: 6324
Maybe wrapping it into lazy
will help?
let x4 = lazy (
printfn "%A" "Long Running stuff"
let addX (x:int) = x + 1
addX)
//val x4 : Lazy<(int -> int)> = Value is not created.
let c = x4.Force() 4
//"Long Running stuff"
//val c : int = 5
c // val it : int = 5
c
Upvotes: 0