将where子句置于GHCi调试器的范围内

ram*_*ion 5 debugging haskell ghci

今天早些时候,我正在尝试调试以下solve功能的一个版本,它给我带来了问题:

newtype Audience = Audience { byShyness :: [Int] }

solve :: Audience -> Int
solve (Audience originalCounts) = numFriendsAdded
  where numFriendsAdded = length $ filter id friendAdded
        friendAdded     = zipWith3 (\i c t -> i >= c + t) [0..] originalCounts alreadyStanding
        alreadyStanding = scanl (+) 0 modifiedCounts
        modifiedCounts  = zipWith (\a c -> if a then 1 else c) friendAdded originalCounts
Run Code Online (Sandbox Code Playgroud)

在GHCi(7.8.2)中,我试图solve通过名称,然后通过行/列来打破,但它似乎没有将where条款中绑定的名称带入范围:

? :b solve 
Breakpoint 0 activated at StandingOvation.hs:(20,1)-(24,89)
? :main StandingOvation.example-input 
Case #1: Stopped at StandingOvation.hs:(20,1)-(24,89)
_result :: Int = _
? numFriendsAdded
<interactive>:5:1: Not in scope: ‘numFriendsAdded’
? :delete 0
? :b 20 35
Breakpoint 1 activated at StandingOvation.hs:20:35-49
? :main StandingOvation.example-input 
Case #1: Stopped at StandingOvation.hs:20:35-49
_result :: Int = _
numFriendsAdded :: Int = _
? numFriendsAdded                                                                                                     
0
? friendAdded
<interactive>:10:1: Not in scope: ‘friendAdded’
Run Code Online (Sandbox Code Playgroud)

显然,就Haskell而言,它们在相互作用范围内,但在调试时我需要做些什么才能使它们可见?

Ørj*_*sen 4

不幸的是,GHCi 调试器并不能让范围内的所有内容在断点处可用。引用用户手册(7.8.2 和 7.10.1(最新)中的文本相同):

GHCi 为断点所在表达式的自由变量 [6] 提供了绑定 ( aleftright),另外还为表达式的结果 ( ) 提供了绑定_result。[...]

和脚注:

[6] 我们最初为范围内的所有变量提供绑定,而不仅仅是表达式的自由变量,但发现这对性能有很大影响,因此当前仅限于自由变量。

本质上,只有在 GHCi 当前停止的表达式中直接提及局部变量时,您才能看到它们。这让我想到了一个解决方法,虽然很愚蠢但确实有效。将函数的主线替换为:

solve (Audience originalCounts) =
    (friendAdded,alreadyStanding,modifiedCounts) `seq` numFriendsAdded
Run Code Online (Sandbox Code Playgroud)

现在,您感兴趣的所有变量都在表达式中提及,因此您可以停下来查看所有变量。