阴影和嵌套function

我想了解阴影和嵌套函数的机制是如何工作的。 例如:

let func y = let dup y = y + y let z = dup y let dup y = let dup z = let y = y * z y let z = y y dup z + z;; val func : int -> int > func 3;; val it : int = 12 

有人可以解释这里发生了什么?

你的代码相当于下面的代码,在这里我简单地对你名字的实例进行了编号,以帮助你可视化阴影的发生。

 let func y0 = let dup0 y1 = y1 + y1 let z0 = dup0 y0 let dup1 y2 = let dup2 z1 = let y3 = y2 * z1 y3 let z2 = y2 y2 dup1 z0 + z0 

当然,这可以进一步简化。 由于dup2z2从不使用, dup1相当于let dup1 y2 = y2 ,整个函数相当于

 let func y0 = let dup0 y1 = y1 + y1 let z0 = dup0 y0 dup1 z0 + z0 

这相当于

 let func y0 = let z0 = y0 + y0 z0 + z0 

通过替代。 这是一样的

 let func y0 = 4 * y0 

这有帮助吗?

我认为@kvb给出了一个非常好的解释,展示了代码如何评估。 该代码以相当混乱的方式组合嵌套函数阴影 :-)。 我认为分别看两个概念是有用的。

阴影允许您通过let声明中的新值或match结构中的值绑定来隐藏值。 这意味着你将不能再访问原始值。 这是一个更简单的例子:

 let foo num = let num = num + 20 // Line 2 let num = num * 2 // Line 3 num 

在这里,我们声明一个函数,它接受一个名为num的参数。 假设我们用1作为参数来调用函数。 在第二行,我们声明一个同名的新值 – 初始化为1 + 20 ,即21 。 第三行再次声明一个新值并将其初始化为21 * 2 (因为它看到最后一个声明的num符号,其值为21 )。 在第四行,我们再次访问最后声明的num符号,我们返回42

这是有用的主要是你有一些计算,计算一些新的价值,应该由所有后续计算使用。 阴影允许你隐藏以前的值,所以没有任何危险,你会不小心使用原来的值。

当需要使用外部函数的参数进行一些本地效用计算时, 嵌套函数非常有用。 例如:

 let times x nums = let timesUtil y = y * x for n in nums do printfn "%d" (timesUtil n) 

这里我们声明一个实用程序嵌套函数timesUtil ,它将任何数字乘以值x (这是times函数的参数)。 然后,我们可以稍后(在最后一行)使用它来执行操作,而无需再次将x值作为parameter passing。 所以,关于嵌套函数的主要有趣之处在于它们可以访问由外部函数声明的值。