因此,我正在通過Real World Haskell的一些初始章節練習,我想知道GHCi中是否有一個選項使其在每次遞歸調用時顯示函數評估參數。例如,我寫了一個簡單的'map'版本,當我應用它時,我希望GHCi用實際參數(並希望表達結果)顯示每個遞歸調用。有些東西可以讓我跟隨幕後發生的事情。ghci顯示執行堆棧
P.S.在我寫這篇文章時,我有一種感覺,它可能會受到哈斯克爾執行模式懶惰的限制,如果我錯了,請糾正我。
因此,我正在通過Real World Haskell的一些初始章節練習,我想知道GHCi中是否有一個選項使其在每次遞歸調用時顯示函數評估參數。例如,我寫了一個簡單的'map'版本,當我應用它時,我希望GHCi用實際參數(並希望表達結果)顯示每個遞歸調用。有些東西可以讓我跟隨幕後發生的事情。ghci顯示執行堆棧
P.S.在我寫這篇文章時,我有一種感覺,它可能會受到哈斯克爾執行模式懶惰的限制,如果我錯了,請糾正我。
您可以使用遮光罩此:
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。
確認在ghci工作7.8.2。 – 2014-10-01 01:46:25
我通常使用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
情況因人而異。
可能的重複[如何在Haskell中調用堆棧?](http://stackoverflow.com/questions/3220869/how-do-i-get-a-callstack-in-haskell) – rampion 2010-07-12 03:49:07
不是真的那個重複。 – jrockway 2010-07-12 11:54:36