+ </para>
+ <sidebar><title>Events</title><?dbfo float-type="left"?>
+ <para> Events are the places in source code where you can set a breakpoint.
+<programlisting>
+qsort [] = <co id="name-binding-co"/> []
+qsort (x:xs) =
+ <coref linkend="name-binding-co"/> let left = <coref linkend="name-binding-co"/> filter (\y -> <co id="lambda-co"/> y < x) xs
+ right = <coref linkend="name-binding-co"/> case filter (\y -> <coref linkend="lambda-co"/> y > x) xs of
+ right_val -> <co id="case-co"/> right_val
+ in <co id="let-co"/> qsort left ++ [x] ++ qsort right
+main = <coref linkend="name-binding-co"/> do {
+ arg <- <coref linkend="name-binding-co"/> getLine ;
+ let num = <coref linkend="name-binding-co"/> read arg :: [Int] ;
+ <co id="stmts-co"/> print (qsort num) ;
+ <coref linkend="stmts-co"/> putStrLn "GoodBye!" }
+</programlisting>
+ The GHCi debugger recognizes the following event types:
+ <calloutlist>
+ <callout arearefs="name-binding-co" id="name-binding">
+ <para>Function definition and local bindings in let/where</para>
+ </callout>
+ <callout arearefs="lambda-co" id="lambda">
+ <para>Lambda expression entry point</para>
+ </callout>
+ <callout arearefs="let-co" id="let">
+ <para>Let expression body</para>
+ </callout>
+ <callout arearefs="case-co" id="case">
+ <para>Case alternative body</para>
+ </callout>
+ <callout arearefs="stmts-co" id="stmts">
+ <para>do notation statements</para>
+ </callout>
+ </calloutlist></para>
+ <para>In reality however, ghci eliminates some redundant event sites.
+ For instance, sites with two co-located breakpoint events are coalesced into a single one,
+ and sites with no bindings in scope are assumed to be uninteresting and no breakpoint can be set in them.</para>
+ </sidebar>
+
+<para>
+ You don't need to do anything special in order to start the debugging session.
+ Simply use ghci to evaluate your Haskell expressions and whenever a breakpoint
+ is hit, the debugger will enter the stage:
+<programlisting>
+*main:Main> :break qsort
+Breakpoint 0 activated at ../QSort.hs:(4,0)-(6,54)
+*QSort> qsort [10,9,1]
+Stopped at ../QSort.hs:(4,0)-(6,54)
+_result :: [a]
+xs :: [a]
+x :: a
+left :: [a]
+right :: [a]
+[../QSort.hs:(4,0)-(6,54)] *QSort>
+</programlisting>
+ What is happening here is that GHCi has interrupted the evaluation of
+ <literal>qsort</literal> at the breakpoint, as the prompt indicates.
+ At this point you can freely explore the contents of the bindings in scope,
+ but with two catches. </para><para>
+ First, take into account that due to the lazy nature of Haskell, some of
+ these bindings may be unevaluated, and that exploring their contents may
+ trigger a computation. </para><para>
+ Second: look at the types of the things in scope.
+ GHCi has left its types parameterised by a variable!
+ Look at the type of <literal>qsort</literal>, which is
+ polymorphic on the type of its argument. It does not
+ tell us really what the types of <literal>x</literal>
+ and <literal>xs</literal> can be.
+ In general, polymorphic functions deal with polymorphic values,
+ and this means that some of the bindings available in a breakpoint site
+ will be parametrically typed.
+ </para><para>
+ So, what can we do with a value without concrete type? Very few interesting
+ things, not even using <literal>show</literal> on it.
+ The <literal>:print</literal> command in ghci allows you to
+ explore its contents and see if it is evaluated or not.
+ <literal>:print</literal> works here because it does not need the
+ type information to do its work. In fact, as we will see later,
+ <literal>:print</literal> can even recover the missing type information.</para>
+
+ <para> Let's go on with the debugging session of the <literal>qsort</literal>
+ example:
+<example id="debuggingEx"><title>A short debugging session</title>
+<programlisting>
+qsort2.hs:2:15-46> x
+<interactive>:1:0:
+ Ambiguous type variable `a' in the constraint: <co id="seq1"/>
+ `Show a' arising from a use of `print' at <interactive>:1:0
+qsort2.hs:2:15-46> seq x () <co id="seq2"/>
+()
+qsort2.hs:2:15-46> x <co id="seq3"/>
+<interactive>:1:0:
+ Ambiguous type variable `a' in the constraint:
+ `Show a' arising from a use of `print' at <interactive>:1:0
+qsort2.hs:2:15-46> :t x
+x :: a
+qsort2.hs:2:15-46> :print x <co id="seq4"/>
+x = 10
+qsort2.hs:2:15-46> :t x <co id="seq5"/>
+x :: Integer
+</programlisting>
+</example>
+ <calloutlist>
+ <callout arearefs="seq1">
+ <para>GHCi reminds us that <literal>x</literal> is untyped </para>
+ </callout>
+ <callout arearefs="seq2">
+ <para>This line forces the evaluation of <literal>x</literal> </para>
+ </callout>
+ <callout arearefs="seq3">
+ <para>Even though x has been evaluated,
+ we have not updated its type yet. </para>
+ </callout>
+ <callout arearefs="seq4">
+ <para>We can explore <literal>x</literal> using the <literal>:print</literal>
+ command, which does find out that <literal>x</literal> is of type Int and
+ prints its value.</para>
+ </callout>
+ <callout arearefs="seq5">
+ <para>In addition, <literal>:print</literal> also updates
+ its type information.</para>
+ </callout>
+ </calloutlist>
+
+ This example shows the standard way to proceeed with polymorphic values in a breakpoint.
+ </para>
+ </sect2>
+ <sect2><title>Commands</title>
+ <para>Breakpoints can be set in several ways using the <literal>:breakpoint</literal> command. Note that you can take advantage of the command abbreviation feature of GHCi and use simply <literal>:bre</literal> to save quite a few keystrokes.
+<variablelist>
+<varlistentry>
+ <term>
+ <literal>:breakpoint add <replaceable>module</replaceable> <replaceable>line</replaceable></literal>
+ </term>
+ <listitem><para>
+ Adds a breakpoint at the first event found at line <literal>line</literal> in <literal>module</literal>, if any.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>
+ <literal>:breakpoint add <replaceable>module</replaceable> <replaceable>line</replaceable> <replaceable>column</replaceable></literal>
+ </term>
+ <listitem><para>
+ Adds a breakpoint at the first event found after column <literal>column</literal>
+ at line <literal>line</literal> in <literal>module</literal>, if any.
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <literal>:breakpoint continue</literal>
+ </term>
+ <listitem><para>
+ When at a breakpoint, continue execution up to the next breakpoint
+ or end of evaluation.
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <literal>:continue</literal>
+ </term>
+ <listitem><para>
+ Shortcut for <literal>:breakpoint continue</literal>
+ </para></listitem>
+</varlistentry>
+
+<varlistentry>
+ <term>
+ <literal>:breakpoint list</literal>
+ </term>
+ <listitem><para>
+ Lists the currently set up breakpoints.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>
+ <literal>:breakpoint del <replaceable>num</replaceable></literal>
+ </term>
+ <listitem><para>
+ Deletes the breakpoint at position <literal>num</literal> in the list of
+ breakpoints shown by <literal>:breakpoint list</literal>.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>
+ <literal>:breakpoint del <replaceable>module</replaceable> <replaceable>line</replaceable></literal>
+ </term>
+ <listitem><para>
+ Dels the breakpoint at line <literal>line</literal> in <literal>module</literal>, if any.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>
+ <literal>:breakpoint del <replaceable>module</replaceable> <replaceable>line</replaceable><replaceable>col</replaceable> </literal>
+ </term>
+ <listitem><para>
+ Deletes the first breakpoint found after column <literal>column</literal>
+ at line <literal>line</literal> in <literal>module</literal>, if any.
+ </para></listitem>
+</varlistentry>
+<varlistentry>
+ <term>
+ <literal>:breakpoint stop </literal>
+ </term>
+ <listitem><para>
+ Stop the program being executed. This interrupts a debugging session
+ and returns to the top level.
+ </para></listitem>
+</varlistentry>
+</variablelist></para>
+ </sect2>
+ <sect2><title>Debugging Higher-Order functions</title>
+ <para>
+ It is possible to use the debugger to examine lambdas.
+ When we are at a breakpoint and a lambda is in scope, the debugger cannot show
+ you the source code that constitutes it; however, it is possible to get some
+ information by applying it to some arguments and observing the result.
+ </para><para>
+ The process is slightly complicated when the binding is polymorphic.
+ We show the process by means of an example.
+ To keep things simple, we will use the well known <literal>map</literal> function:
+ <programlisting>
+import Prelude hiding (map)
+
+map :: (a->b) -> a -> b
+map f [] = []
+map f (x:xs) = f x : map f xs
+ </programlisting>
+ </para><para>
+ We set a breakpoint on <literal>map</literal>, and call it.
+ <programlisting>
+*Main> :break map
+Breakpoint 0 activated at map.hs:(4,0)-(5,12)
+*Main> map Just [1..5]
+Stopped at map.hs:(4,0)-(5,12)
+_result :: [b]
+x :: a
+f :: a -> b
+xs :: [a]
+ </programlisting>
+ GHCi tells us that, among other bindings, <literal>f</literal> is in scope.
+ However, its type is not fully known yet,
+ and thus it is not possible to apply it to any
+ arguments. Nevertheless, observe that the type of its first argument is the
+ same as the type of <literal>x</literal>, and its result type is the
+ same as the type of <literal>_result</literal>.
+ </para><para>
+ The debugger has some intelligence built-in to update the type of
+ <literal>f</literal> whenever the types of <literal>x</literal> or
+ <literal>_result</literal> are reconstructed. So what we do in this scenario is
+ force <literal>x</literal> a bit, in order to recover both its type
+ and the argument part of <literal>f</literal>.
+ <programlisting>
+*Main> seq x ()
+*Main> :print x
+x = 1
+ </programlisting>
+ </para><para>
+ We can check now that as expected, the type of <literal>x</literal>
+ has been reconstructed, and with it the
+ type of <literal>f</literal> has been too:
+ <programlisting>
+*Main> :t x
+x :: Integer
+*Main> :t f
+f :: Integer -> b
+ </programlisting>
+ </para><para>
+ From here, we can apply f to any argument of type Integer and observe the
+ results.
+ <programlisting><![CDATA[
+*Main> let b = f 10
+*Main> :t b
+b :: b
+*Main> b
+<interactive>:1:0:
+ Ambiguous type variable `b' in the constraint:
+ `Show b' arising from a use of `print' at <interactive>:1:0
+*Main> :p b
+b = (_t2::a)
+*Main> seq b ()
+()
+*Main> :t b
+b :: a
+*Main> :p b
+b = Just 10
+*Main> :t b
+b :: Maybe Integer
+*Main> :t f
+f :: Integer -> Maybe Integer
+*Main> f 20
+Just 20
+*Main> map f [1..5]
+[Just 1, Just 2, Just 3, Just 4, Just 5]
+ ]]></programlisting>
+ In the first application of <literal>f</literal>, we had to do
+ some more type reconstruction
+ in order to recover the result type of <literal>f</literal>.
+ But after that, we are free to use
+ <literal>f</literal> normally.
+ </para>
+ </sect2>
+ <sect2><title>Tips</title>
+ <variablelist>
+ <varlistentry> <term>* Repeated use of <literal>seq</literal> and
+ <literal>:print</literal> may be necessary to observe unevaluated
+ untyped bindings</term>
+ <listitem><para>see <xref linkend="debuggingEx"/>
+ </para></listitem>
+ </varlistentry>
+ <varlistentry> <term> * <literal>GHC.Exts.unsafeCoerce</literal> can help if you are positive about the type of a binding</term>
+ <listitem><para><programlisting>
+type MyLongType a = [Maybe [Maybe a]]
+
+*Main> :m +GHC.Exts
+*Main> main
+Local bindings in scope:
+ x :: a
+Main.hs:15> let x' = unsafeCoerce x :: MyLongType Bool
+Main.hs:15> x'
+[Just [Just False, Just True]]
+ </programlisting>
+ Note that a wrong coercion will likely result in your debugging session being interrupted by a segmentation fault
+ </para></listitem>
+ </varlistentry>
+ <varlistentry> <term> * The <literal>:force</literal> command </term>
+ <listitem><para>
+ equivalent to <literal> :print</literal> with automatic
+ <literal>seq</literal> forcing,
+ may prove useful to replace sequences of <literal>seq</literal> and
+ <literal>:print</literal> in some situations.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+ </sect2>
+ <sect2><title>Limitations</title>
+ <para>
+ <itemizedlist>
+ <listitem><para>
+ Implicit parameters (see <xref linkend="implicit-parameters"/>) are only available
+ at the scope of a breakpoint if there is a explicit type signature.
+ </para></listitem>
+ </itemizedlist>
+ </para>
+ </sect2>
+ </sect1>