今天早些时候,我正在尝试调试以下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而言,它们处于相互作用范围内,但在调试时我需要做些什么才能使它们可见?
答案 0 :(得分:4)
不幸的是,GHCi调试器并没有在断点处提供范围内的所有内容。引用from the user manual(7.8.2和7.10.1(最新)中相同的文字):
GHCi为放置断点的表达式的自由变量[6]提供了绑定(
a
,left
,right
),并且还为结果提供了绑定表达式(_result
)。 [...]
和脚注:
[6]我们最初为范围内的所有变量提供了绑定,而不仅仅是表达式的自由变量,但发现这会显着影响性能,因此当前只限于自由变量。
基本上,如果直接在GHCi当前停止的表达式中提到它们,则只能看到局部变量。这让我想到了一个解决方法,虽然很傻但确实有效。用以下方法替换函数的主线:
solve (Audience originalCounts) =
(friendAdded,alreadyStanding,modifiedCounts) `seq` numFriendsAdded
现在,您在表达式中提到了您感兴趣的所有变量,因此您可以停下来查看它们。