带有读入其他数据文件的行的函数

时间:2017-01-30 22:10:22

标签: f#

我有一个具有示例功能的控制台应用程序:

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)

函数中如何使用ci变量?他们是否在最后两行之前读了一次并且只是重复使用,因为aList很长?或者它们是否为“aList”中的每个q执行一次?

如果是后者,是否有更好的方法来编写这样的函数?我可以以某种方式编写函数,以便ci仅运行一次,但在aList中需要多次传递吗?

2 个答案:

答案 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