当 lambda 表达式按值或按引用使用时,GHC 如何捕获变量的环境?

问题描述 投票:0回答:1

在这篇 stackoverflow 帖子 中,有一些 C++ 代码试图模仿关联类型。当 lambda 函数使用引用捕获捕获环境(闭包)时,代码可以编译,但在运行时失败。当代码更改为按值捕获时,代码在编译时和运行时都会成功。 GHC 如何通过引用或值捕获 lambda 函数的闭包?

c++ haskell lambda ghc
1个回答
0
投票

GHC 通过引用捕获闭包中的变量,但是 (1) 因为所有值都分配在垃圾收集堆上,所以引用在闭包的生命周期内保持有效,因此不会像 C++ 示例中那样出现运行时错误; (2) 因为 Haskell 值是不可变的,所以程序的行为基本上与通过值捕获闭包相同,因为引用的值在 Haskell 程序的生命周期中不会改变。

所以,例如在程序中:

subtracter :: Integer -> (Integer -> Integer)
subtracter delta = let increment = -delta in \x -> x + increment

调用

subtracter 42
的结果是一个 lambda
x -> x + increment
,它通过引用捕获了
increment
的值。 即使
increment
是一个“局部变量”(或接近 Haskell 中的局部变量),它仍然是对堆上不可变值
-42
的引用,而不是堆栈上的可变值,就像 C++ 一样。 因此,该引用在 lambda 的生命周期内保持有效,并且始终是对值
-42
的不可变引用,因此效果与 lambda “按值”捕获它一样
-42
.

© www.soinside.com 2019 - 2024. All rights reserved.