Here's a trivial wai
/warp
program so I can learn how ghci
debugger actually works:-
{-# 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
In ghci
, I first load this program (e.g. with :load hellowai.hs
).
Then, I set my break points in line 9 and line 10 with
:break 9
:break 10
Then, in ghci
, I execute main
.
I then run localhost:3000
on my browser or with curl (doesn't matter of course) and my program breaks at line 9 as expected.
How do I print out (introspect) x
and how do I introspect req
?
I tried using :print
and ghci
simply complains "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>
With the GHCi command :print ...
(or :sprint ...
) you can print out the variables in scope. This however will print only evaluated values (recall Haskell is lazy).
To evaluate and print, just use the name of the variables directly. You can get a list of the variables in scope with the :show bindings
command.
If you do not see the variables in scope, it is possible that they have been optimized away by the compilier. In your code, you do not use x
, so that is likely removed during compilation. Also, code such as
foo = do
let x = 3
print "aa"
print "bb"
print x
is probably handled as (line numbers aside)
foo = do
print "aa"
print "bb"
let x = 3
print x
So you will not see x
in scope until the last line. In such cases, use :step
to advance your execution a little until you see x
appear.