gpt4 book ai didi

haskell - GHCi 调试器没有递归地命中断点 : Why, 解决方案是什么?

转载 作者:行者123 更新时间:2023-12-02 15:18:11 24 4
gpt4 key购买 nike

我有一个不太有效的简单递归程序。所以我正在尝试使用 ghci 调试器来弄清楚发生了什么。我在函数 recurseprogressshaded 的所有行上都设置了断点,它捕获了前几个。但是当我到达 progress 的第二行时,每次调用 :continue 都会让我回到同一行代码,即使我正在调用 recurseshaded 从那里开始并期待我的断点起作用。这是代码:

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com