在 wai/warp 应用程序中使用 ghci 调试器



这是一个微不足道的wai/warp程序,所以我可以了解调试器的实际工作原理ghci

{-# LANGUAGE OverloadedStrings #-}
import Network.Wai
import Network.HTTP.Types (status200)
import Network.Wai.Handler.Warp (run)
import Debug.Trace (trace)
myApp req respond = do 
    let x = 1 {- line 8 -}
    putStrLn "processing request" {- line 9 -}
    putStrLn "Hoooray!" {- line 10 -}
    respond $ responseLBS status200 [("Content-Type", "text/plain")] "Hello World" 
main = run 3000 myApp 

ghci中,我首先加载这个程序(例如用:load hellowai.hs)。

然后,我在第 9 行和第 10 行中设置断点

:break 9
:break 10

然后,在ghci,我执行main

然后我在浏览器上运行localhost:3000或使用 curl(当然没关系),我的程序按预期在第 9 行中断。

如何打印(内省)x以及如何内省req

我尝试使用:printghci只是抱怨"不在范围内"。

Stopped at hellowai.hs:9:5-33
_result :: IO () = _
[hellowai.hs:9:5-33] *Main> :print x
Top level: Not in scope: ‘x’
[hellowai.hs:9:5-33] *Main> :print req
Top level:
    Not in scope: ‘req’
    Perhaps you meant one of these:
      ‘rem’ (imported from Prelude), ‘seq’ (imported from Prelude)
[hellowai.hs:9:5-33] *Main>

使用 GHCi 命令 :print ... (或 :sprint ... ),您可以打印出范围内的变量。但是,这将仅打印计算值(回想一下Haskell很懒惰)。

要计算和打印,只需直接使用变量的名称。您可以使用 :show bindings 命令获取范围内的变量列表。

如果在作用域中看不到变量,则可能是编译器对它们进行了优化。在您的代码中,您不使用 x ,因此在编译过程中可能会将其删除。此外,诸如

foo = do
  let x = 3
  print "aa"
  print "bb"
  print x

可能处理为(行号除外)

foo = do
  print "aa"
  print "bb"
  let x = 3
  print x

因此,直到最后一行,您才会看到范围内的x。在这种情况下,请使用:step稍微提前执行,直到看到x出现。

最新更新