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

Using ghci debugger in a wai/warp app

这是一个简单的 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

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

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

我尝试使用 :printghci 只是抱怨 "Not in scope"。

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 出现。