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

时间:2015-04-12 03:50:57

标签: 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

在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’

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

1 个答案:

答案 0 :(得分:4)

不幸的是,GHCi调试器并没有在断点处提供范围内的所有内容。引用from the user manual(7.8.2和7.10.1(最新)中相同的文字):

  

GHCi为放置断点的表达式的自由变量[6]提供了绑定(aleftright),并且还为结果提供了绑定表达式(_result)。 [...]

和脚注:

  

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

基本上,如果直接在GHCi当前停止的表达式中提到它们,则只能看到局部变量。这让我想到了一个解决方法,虽然很傻但确实有效。用以下方法替换函数的主线:

solve (Audience originalCounts) =
    (friendAdded,alreadyStanding,modifiedCounts) `seq` numFriendsAdded

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