GHCi 如何处理中断?

How are interruptions handled in GHCi?

我正在试验 GHCi 的 :sprint 命令。考虑以下因素:

GHCi> xs = [1..10] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
10
GHCi> :sprint xs
xs = [1,2,3,4,5,6,7,8,9,10]

这按预期工作。我感兴趣的是 :sprint 在我们中断一些计算后的行为。考虑以下因素:

GHCi> xs = [1..] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
Interrupted.
GHCi> :sprint xs

它挂起。

预期的结果是这样的(模数 :s):

xs = _ : _ : _ : _

什么原因导致 :sprint ... 冻结?为什么无法访问有关已计算的列表部分的信息?对我来说这似乎是一个错误 - 没有真正的理由放弃被打断的 length 所做的所有工作。这确实是一个错误,还是我错了?

正如@Daniel Wagner 在评论中解释的那样,GHCi 实际上完全 符合您的预期。它似乎挂起,因为 length 非常快,并且评估大量元素,这需要 :sprint 一些时间来漂亮地打印到一个字符串。与普通的 GHCi 输出不同,:sprint 在开始打印之前强制它的字符串值。如果您等待足够长的时间,:sprint 确实会按预期打印部分字符串。

您可以按如下方式进行演示:

GHCi> xs = [1..100000] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> xs
[1,2,3,4 ... 8504^CInterrupted.
GHCi> :sprint xs
1 : 2 : 3 : 4 : ... : 8504 : _