作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个不太有效的简单递归程序。所以我正在尝试使用 ghci 调试器来弄清楚发生了什么。我在函数 recurse
、progress
和 shaded
的所有行上都设置了断点,它捕获了前几个。但是当我到达 progress
的第二行时,每次调用 :continue 都会让我回到同一行代码,即使我正在调用 recurse
和 shaded
从那里开始并期待我的断点起作用。这是代码:
import System.Environment
type Pos = (Int,Int)
type Acc = ([[Pos]], [Pos])
main = do
getArgs >>= putStrLn . show . length . combos . read . head
combos n = recurse n [] (allPos n) []
recurse :: Int -> [[Pos]] -> [Pos] -> [Pos] -> [[Pos]]
recurse n done avail inProg
| length inProg == n = inProg:done
| null avail = done
| otherwise = fst $ foldr (progress n inProg) (done,avail) avail
progress :: Int -> [Pos] -> Pos -> Acc -> Acc
progress n inProg pos (done, avail) =
(recurse n done (filter (not . shaded pos) remain) (pos:inProg), remain)
where remain = tail avail
allPos n = [ (i,j) | i <- [0..n-1], j <- [0..n-1] ]
shaded :: Pos -> Pos -> Bool
shaded (i,j) (k,l) =
k == i
|| l == j
|| k+l == i+j
|| k-l == i-j
|| abs (k-i) < 3 && abs (l-j) < 3
为什么 ghci 调试器不会在 progress
调用的函数中的断点处停止?是否有类似“不可重入”的东西将它们关闭?我怎样才能让调试器在每次递归调用这些函数时中断?
GHCi 版本 7.8.4
更新:我怀疑这可能与缓存的结果有关,但我并不清楚这些函数是否已使用相同的参数被调用两次。可能是我的代码中的错误?
最佳答案
我认为它按预期工作,但你必须考虑惰性求值。
如果你在 recurse
中突破警戒线(第 13 - 15 行)和递归调用(第 19 行),当程序以 :main 2
运行时,您将看到这种模式。 :
Stopped at prog0.hs:13:6-23 - recurse
Stopped at prog0.hs:14:6-15 - recurse
Stopped at prog0.hs:15:18-67 - recurse, call to foldr progress
Stopped at prog0.hs:19:3-74 - in progress, pos = (1,1)
Stopped at prog0.hs:19:3-74 - in progress, pos = (1,0)
Stopped at prog0.hs:19:3-74 - in progress, pos = (0,1)
Stopped at prog0.hs:19:3-74 - in progress, pos = (0,0)
Stopped at prog0.hs:13:6-23 - in recurse
Stopped at prog0.hs:14:6-15
Stopped at prog0.hs:13:6-23 - in recurse
Stopped at prog0.hs:14:6-15
Stopped at prog0.hs:13:6-23 - in recurse
Stopped at prog0.hs:14:6-15
Stopped at prog0.hs:13:6-23 - in recurse
Stopped at prog0.hs:14:6-15
但是,如果您更改 progress
强制其结果:
import Control.DeepSeq
progress n inProg pos (done, avail) = let
result = (recurse n done (filter (not . shaded pos) remain) (pos:inProg), remain)
in deepseq result result
where remain = tail avail
那么断点模式是:
Stopped at prog1.hs:14:6-23 - recurse
Stopped at prog1.hs:15:6-15 - recurse
Stopped at prog1.hs:16:18-67 - recurse, call to foldr progress
Stopped at prog1.hs:21:6-26 - progress, pos = (1,1)
Stopped at prog1.hs:14:6-23 - recurse
Stopped at prog1.hs:15:6-15
Stopped at prog1.hs:21:6-26 - progress, pos = (1,0)
Stopped at prog1.hs:14:6-23 - recurse
Stopped at prog1.hs:15:6-15
Stopped at prog1.hs:21:6-26 - progress, pos = (0,1)
Stopped at prog1.hs:14:6-23 - recurse
Stopped at prog1.hs:15:6-15
Stopped at prog1.hs:21:6-26 - progress, pos = (0,0)
Stopped at prog1.hs:14:6-23 - recurse
Stopped at prog1.hs:15:6-15
递归调用 recurse
现在是交错的,因为我们立即强制他们。
关于haskell - GHCi 调试器没有递归地命中断点 : Why, 解决方案是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39109267/
我是一名优秀的程序员,十分优秀!