ghci显示执行堆栈

时间:2010-07-12 02:11:31

标签: ghci haskell

所以我正在完成Real World Haskell的一些初步章节练习,我想知道GHCi中是否有一个选项让它在每次递归调用时显示带参数的函数评估。所以例如我写了一个简单版本的'map',当我应用它时,我希望GHCi用实际参数显示每个递归调用(希望表达式结果)。能让我跟踪幕后发生的事情。

P.S。当我写这篇文章时,我感觉它可能受到哈斯克尔执行模型的懒惰的限制,如果我错了就纠正我。

3 个答案:

答案 0 :(得分:3)

你可以使用引擎盖:

import Debug.Hood.Observe

map2 f [] = []
map2 f (x:xs) = f x : (observe "map2" $ map2) f xs

main = runO $ print $ map2 (+1) ([1..10] :: [Int])

运行它时,它将使用相应的参数和返回的结果打印每次调用map2。你会看到类似的东西:

.
.
.
-- map2
{ \ { \ 10  -> 11
    , \ 9  -> 10
    } (9 : 10 : []) 
    -> 10 : 11 : []
}
-- map2
{ \ { \ 10  -> 11
    } (10 : []) 
    -> 11 : []
}
-- map2
{ \ _ []  -> []
}

有关详情,请查看examples

答案 1 :(得分:3)

我通常使用Debug.Trace

import Debug.Trace

buggy acc xs | traceShow (acc,xs) False = undefined
buggy acc []     = acc
buggy acc (x:xs) = buggy (acc + x) xs

main = print $ buggy 0 [1..10]

这让我看到了越野车功能如何运作:

(0,[1,2,3,4,5,6,7,8,9,10])
(1,[2,3,4,5,6,7,8,9,10])
(3,[3,4,5,6,7,8,9,10])
(6,[4,5,6,7,8,9,10])
(10,[5,6,7,8,9,10])
(15,[6,7,8,9,10])
(21,[7,8,9,10])
(28,[8,9,10])
(36,[9,10])
(45,[10])
(55,[])
55

关键是具有永不匹配的模式,但在不匹配的情况下打印某些内容。这样它总是被评估(因此打印调试信息),并且很容易适应任何功能。但是如果您只想查看某些情况,也可以将其匹配,例如:

buggy acc [] = acc
buggy acc (x:xs) | traceShow (acc, x, xs) True = buggy (acc + x) xs

然后你只能在非基本情况下得到调试输出:

(0,1,[2,3,4,5,6,7,8,9,10])
(1,2,[3,4,5,6,7,8,9,10])
(3,3,[4,5,6,7,8,9,10])
(6,4,[5,6,7,8,9,10])
(10,5,[6,7,8,9,10])
(15,6,[7,8,9,10])
(21,7,[8,9,10])
(28,8,[9,10])
(36,9,[10])
(45,10,[])
55

因人而异。

答案 2 :(得分:2)