这个问题是基于我之前的一个有关可变值的问题 (原问题链接) 扩展而来。 我非常确定这个问题的主题,预计算,与链接的问题有很多关联。
请看下面的例子,这些例子来自我正在学习的书:
我原本以为这两个函数做的事情完全一样,但实际上并非如此。据书上所说,第一个函数会从给定的列表中预先计算集合,而第二个函数则是在每次调用函数时才计算集合。
正如我在PL课程中学到的那样,为了评估lambda演算表达式,必须将每个参数传递给主体。如果缺少任何一个参数,表达式就无法被评估。
基于此,我得出结论:第一个函数没有参数,所以当列表被提供时,它可以立即开始评估;而第二个函数直到参数
从以上问题和答案出发思考,似乎只要存在无需特定情况的表达式部分,就会被评估并进行预计算,只会执行一次,就像第一个例子一样。这可能对优化和性能产生很大影响,因此我想澄清自己对这个主题的理解。
请看下面的例子,这些例子来自我正在学习的书:
let isWord (words : string list) =
let wordTable = Set.ofList words // Expensive computation!
fun w -> wordTable.Contains(w)
val isWord : words:string list -> (string -> bool)
这个函数接受一个字符串列表,返回一个检查输入字符串是否在列表中的函数。有了这个小巧可爱的辅助函数,我们来看两个例子:
let isCapital = isWord ["London"; "Paris"; "Warsaw"; "Tokyo"];;
val isCapital : (string -> bool)
let isCapitalSlow word = isWord ["London"; "Paris"; "Warsaw"; "Tokyo"] word
val isCapitalSlow : (string -> bool)
我原本以为这两个函数做的事情完全一样,但实际上并非如此。据书上所说,第一个函数会从给定的列表中预先计算集合,而第二个函数则是在每次调用函数时才计算集合。
正如我在PL课程中学到的那样,为了评估lambda演算表达式,必须将每个参数传递给主体。如果缺少任何一个参数,表达式就无法被评估。
基于此,我得出结论:第一个函数没有参数,所以当列表被提供时,它可以立即开始评估;而第二个函数直到参数
word
被给定才开始评估。到这里还好,但是在思考以上链接的问题后,我不确定我的理解是否正确。从以上问题和答案出发思考,似乎只要存在无需特定情况的表达式部分,就会被评估并进行预计算,只会执行一次,就像第一个例子一样。这可能对优化和性能产生很大影响,因此我想澄清自己对这个主题的理解。