我有一个具有示例功能的控制台应用程序:
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)
函数中如何使用c
和i
变量?他们是否在最后两行之前读了一次并且只是重复使用,因为aList
很长?或者它们是否为“aList”中的每个q
执行一次?
如果是后者,是否有更好的方法来编写这样的函数?我可以以某种方式编写函数,以便c
和i
仅运行一次,但在aList
中需要多次传递吗?
答案 0 :(得分:2)
最明显的解决方案是将它们移出功能体:
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)
通常,如果您的函数是在模块内声明的,那么这两个let绑定可以在与函数相同的级别声明,在本例中是在模块级别。
这是我要考虑的第一件事。现在,如果您希望在第一次调用aFxUsedFromTheEntryPoint
函数时调用它们,那么您可以使用其他技术,如memoization或惰性值,如另一个答案中所述,但请注意,对函数的第一次调用将是比后续电话慢。
答案 1 :(得分:0)
将它包装到lazy
中会有帮助吗?
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