我想了解阴影和嵌套函数的机制是如何工作的.例如:
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
Run Code Online (Sandbox Code Playgroud)
有人可以解释这里发生了什么吗
kvb*_*kvb 16
您的代码等同于以下内容,我只是简单地编号您的名称实例,以帮助您可视化阴影的发生方式.
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
Run Code Online (Sandbox Code Playgroud)
当然,这可以进一步简化.既然dup2和z2从未使用过,dup1相当于let dup1 y2 = y2,而且整个功能相当于
let func y0 =
let dup0 y1 = y1 + y1
let z0 = dup0 y0
dup1 z0 + z0
Run Code Online (Sandbox Code Playgroud)
这相当于
let func y0 =
let z0 = y0 + y0
z0 + z0
Run Code Online (Sandbox Code Playgroud)
通过替代.这是一样的
let func y0 = 4 * y0
Run Code Online (Sandbox Code Playgroud)
这有帮助吗?
Tom*_*cek 13
我认为@kvb给出了一个非常好的解释,显示了代码的评估方式.该代码以一种非常令人困惑的方式结合了嵌套函数和阴影 :-).我认为分别研究这两个概念是有用的.
阴影允许您通过let声明中的新值或match构造中的值绑定隐藏值.这意味着您将无法再访问原始值.这是一个更简单的例子:
let foo num =
let num = num + 20 // Line 2
let num = num * 2 // Line 3
num
Run Code Online (Sandbox Code Playgroud)
在这里,我们声明一个带有一个名为的参数的函数num.假设我们用1作为参数调用函数.在第二行,我们声明一个具有相同名称的新值 - 初始化为1 + 20,即21.第三行再次声明一个新值并将其初始化为21*2(因为它看到最后声明的num符号,其值为21).在第4行,我们再次访问最后声明的num符号,然后返回42.
这很有用,主要是你有一些计算可以计算一些新值,这些值应该被所有后续计算使用.阴影允许您隐藏以前的值,因此不会有意外使用原始值的危险.
当您需要使用外部函数的参数进行一些本地实用程序计算时,嵌套函数非常有用.例如:
let times x nums =
let timesUtil y = y * x
for n in nums do
printfn "%d" (timesUtil n)
Run Code Online (Sandbox Code Playgroud)
这里我们声明一个实用程序嵌套函数timesUtil,它将任意数字乘以该值x(这是times函数的参数).然后我们可以稍后(在最后一行)使用它来执行操作,而不必x再次将值作为参数传递.因此,嵌套函数的主要有趣之处在于它们可以访问外部函数声明的值.