https://wiki.haskell.org/api.php?action=feedcontributions&user=AudreyTang&feedformat=atomHaskellWiki - User contributions [en]2024-03-19T14:06:02ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Bottom&diff=58338Bottom2014-06-16T09:04:26Z<p>AudreyTang: Actual undefined definition from ghci</p>
<hr />
<div>The term '''bottom''' refers to a computation which never completes successfully. That includes a computation that fails due to some kind of error, and a computation that just goes into an infinite loop (without returning any data).<br />
<br />
The mathematical symbol for bottom is '&perp;'. That's Unicode character 22A5 hex = 8869 decimal. Also available in HTML as '&amp;perp;' and in LaTeX as '\bot' (within math mode). In plain ASCII, it's often written as the extremely ugly character sequence '<code>_|_</code>'.<br />
<br />
Bottom is a member of any type, even the trivial type () or the equivalent simple type:<br />
<br />
<haskell><br />
data Unary = Unary<br />
</haskell><br />
<br />
If it were not, the compiler could solve the [http://en.wikipedia.org/wiki/Halting_problem halting problem] and statically determine whether any computation terminated (though note that some languages with dependent type systems, such as [http://en.wikipedia.org/wiki/Epigram_%28programming_language%29 Epigram], can statically enforce termination, based on the type for particular programs, such as those using induction).<br />
<br />
Bottom can be expressed in Haskell thus:<br />
<br />
<haskell><br />
bottom = bottom<br />
</haskell><br />
<br />
or<br />
<br />
<haskell><br />
bottom = error "Non-terminating computation!"<br />
</haskell><br />
<br />
Indeed, the Prelude exports a function <br />
<br />
<haskell><br />
undefined = error "Prelude.undefined"<br />
</haskell><br />
<br />
Other implementations of Haskell, such as Gofer, defined bottom as:<br />
<br />
<haskell><br />
undefined | False = undefined<br />
</haskell><br />
<br />
The type of bottom is arbitrary, and defaults to the most general type:<br />
<br />
<haskell><br />
undefined :: a<br />
</haskell><br />
<br />
As bottom is an inhabitant of every type (though with some caveats concerning types of unboxed kind), bottoms can be used wherever a value of that type would be. This can be useful in a number of circumstances:<br />
<br />
<haskell><br />
-- For leaving a todo in your program to come back to later:<br />
foo = undefined<br />
<br />
-- When dispatching to a type class instance:<br />
print (sizeOf (undefined :: Int))<br />
<br />
-- When using laziness:<br />
<br />
print (head (1 : undefined))<br />
<br />
</haskell><br />
<br />
[[Category:Glossary]]</div>AudreyTanghttps://wiki.haskell.org/index.php?title=Debugging&diff=21458Debugging2008-06-25T01:51:11Z<p>AudreyTang: typo</p>
<hr />
<div>== Printf and friends ==<br />
The simplest approach is to use <tt>Debug.Trace.trace</tt>:<br />
<pre><br />
trace :: String -> a -> a<br />
</pre><br />
: "''When called, trace outputs the string in its first argument, before returning the second argument as its result.'"<br />
<br />
A common idiom to trace a function is:<br />
<pre><br />
myfun a b | trace ("myfun " ++ show a ++ " " ++ show b) False = undefined<br />
myfun a b = ...<br />
</pre><br />
The advantage is that disabling and enabling the trace takes only one line comment.<br />
<br />
You must keep in mind that due to lazy evaluation your traces will only print if the value they wrap is ever demanded.<br />
<br />
<br />
A more powerful<br />
alternative for this approach is [http://www.haskell.org/hood Hood]. Even if it hasn't been<br />
updated in some time, Hood works perfectly with the current ghc<br />
distribution. Even more, Hugs has it already integrated, see the [http://cvs.haskell.org/Hugs/pages/users_guide/observe.html manual page]. Add an <tt>import Observe</tt> and start inserting observations in your code.<br />
For instance:<br />
<pre><br />
import Hugs.Observe<br />
<br />
f' = observe "Informative name for f" f <br />
f x = if odd x then x*2 else 0<br />
</pre><br />
And then in hugs:<br />
<pre><br />
Main> map f' [1..5]<br />
[2,0,6,0,10]<br />
<br />
>>>>>>> Observations <<<<<<<br />
<br />
Informative name for f<br />
{ \ 5 -> 10<br />
, \ 4 -> 0<br />
, \ 3 -> 6<br />
, \ 2 -> 0<br />
, \ 1 -> 2<br />
}<br />
<br />
</pre><br />
<br />
outputs a report of all the invocations of f and their result.<br />
<br />
I have a handy bogus Hugs.Observe module with no-ops for the observations so that I don't need to remove them manually, expecting that the compiler will optimize them away. <br />
<br />
<br />
== The Safe Library ==<br />
<br />
There is a safe library of functions from the Prelude that can crash, see [http://www-users.cs.york.ac.uk/~ndm/safe/ the safe library]. If you get an error message such as "pattern match failure, head []", you can then use <tt>headNote "extra information"</tt> to get a more detailed error message for that particular call to <tt>head</tt>. The safe library also has functions that return default values and wrap their computation in <tt>Maybe</tt> as required.<br />
<br />
== Offline analysis of traces ==<br />
The most advanced debugging tools are based in offline analysis of traces. [http://www.haskell.org/hat Hat] is probably the most up-to-date tool for this, offering a comprehensive set of tools. [[User:NeilMitchell|Neil Mitchell]] has made available a Windows port of Hat at [http://www-users.cs.york.ac.uk/~ndm/projects/windows.php his site].<br />
<br />
The disadvantage of these tools is that they are not always compatible with the latest libraries, so you can put them to use only in some cases. <br />
<br />
''Some Hat user should complete this section''<br />
<br />
== Dynamic breakpoints in GHCi == <br />
Finally, the [[GHC/GHCi debugger| GHCi debugger]] project aims to bring dynamic<br />
breakpoints and intermediate values observation to GHCi in a near<br />
future. Right now the tool is only available from the site as a<br />
modified version of GHC, so unfortunately you will have to compile it<br />
yourself if you want to have it.<br />
<br />
This tool allows to set breakpoints in your code, directly from the GHCi command prompt. An example session:<br />
<pre><br />
*main:Main> :break add Main 2<br />
Breakpoint set at (2,15)<br />
*main:Main> qsort [10,9..1]<br />
Local bindings in scope:<br />
x :: a, xs :: [a], left :: [a], right :: [a]<br />
<br />
qsort2.hs:2:15-46> :sprint x<br />
x = _<br />
qsort2.hs:2:15-46> x<br />
This is an untyped, unevaluated computation. You can use seq to <br />
force its evaluation and then :print to recover its type<br />
qsort2.hs:2:15-46> seq x ()<br />
() <br />
qsort2.hs:2:15-46> :p x<br />
x - 10<br />
</pre><br />
<br />
Once a breakpoint is hit, you can explore the bindings in scope, as well as to evaluate any haskell expression, as you would do in a normal GHCi prompt. The <tt>':print'</tt> command can be very useful to explore the lazyness of your code.<br />
<br />
== Source-located errors ==<br />
<br />
[http://www.cse.unsw.edu.au/~dons/loch.html LocH] provides wrappers over<br />
<hask>assert</hask> for generating source-located exceptions and errors.<br />
<br />
Consider the use of a located <hask>fromJust</hask>:<br />
<br />
<haskell><br />
import Debug.Trace.Location<br />
import qualified Data.Map as M<br />
import Data.Maybe<br />
<br />
main = do print f<br />
<br />
f = let m = M.fromList<br />
[(1,"1")<br />
,(2,"2")<br />
,(3,"3")]<br />
s = M.lookup 4 m<br />
in fromJustSafe assert s<br />
<br />
fromJustSafe a s = check a (fromJust s)<br />
</haskell><br />
<br />
This will result in:<br />
<br />
<haskell><br />
$ ./a.out<br />
a.out: A.hs:12:20-25: Maybe.fromJust: Nothing<br />
</haskell><br />
<br />
This can be automated, using the 'loch' preprocessor, so a program<br />
failing with:<br />
<br />
<code><br />
$ ghc A.hs --make -no-recomp<br />
[1 of 1] Compiling Main ( A.hs, A.o )<br />
Linking A ...<br />
<br />
$ ./A<br />
A: Maybe.fromJust: Nothing<br />
</code><br />
<br />
Can be transformed to a src-located one by adding:<br />
<br />
<haskell><br />
import Debug.Trace.Location<br />
</haskell><br />
<br />
and then recompiling with the preprocessor on:<br />
<br />
<code><br />
$ ghc A.hs --make -pgmF loch -F -no-recomp<br />
[1 of 1] Compiling Main ( A.hs, A.o )<br />
Linking A ...<br />
<br />
$ ./A<br />
A: A.hs:14:14-19: Maybe.fromJust: Nothing<br />
</code><br />
<br />
== Other tricks ==<br />
<br />
* If you use GHC, you can get a stack trace in the console when your program fails with an error condition. See the [http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-options-debugging manual page]<br />
<br />
=== Locating a failure in a library function ===<br />
<br />
The simplest way to provide locating in the source code a mismatch<br />
run-time error in the library functions:<br />
<haskell><br />
head, tail, fromJust<br />
</haskell><br />
<br />
and others is to avoid these functions and to use explicit matching instead.<br />
<br />
For example, consider:<br />
<br />
<haskell><br />
g x = h $ fromJust $ f x,<br />
</haskell><br />
<br />
ghc-6.6 often looses the reference to <hask>g</hask>, <hask>f</hask>,<br />
and <hask>h</hask> in its run-time error report, when <hask>f</hask><br />
returns <hask>Nothing</hask>.<br />
<br />
But for the program:<br />
<br />
<haskell><br />
g x = let Just y = f x in h y,<br />
</haskell><br />
<br />
GHC reports:<br />
<br />
<haskell><br />
Main: M1.hs:9:11-22:<br />
Irrefutable pattern failed for pattern Data.Maybe.Just y<br />
</haskell><br />
<br />
Indicating the source of the failure.<br />
<br />
=== Mysterious parse errors ===<br />
<br />
GHC provides `-ferror-spans`, which will give you the exactly position<br />
of the start and end of an offending statement.<br />
<br />
[[Category:Tools]]<br />
<br />
=== Infinite loops ===<br />
On glasgow-haskell-users on 21 Nov 2007, pepe made the following suggestion for detecting the cause infinite loops in GHCi. Assuming the offending function is named `loop`, and takes one argument:<br />
<br />
# enable the flag -fbreak-on-error (`:set -fbreak-on-error` in GHCi)<br />
# run your expression with :trace (`:trace loop 'a'`)<br />
# hit Ctrl-C while your program is stuck in the loop to have the debugger break in the loop<br />
# use :history and :back to find out where the loop is located and why.<br />
<br />
''(For which versions? ghci >= 6.8?)''</div>AudreyTanghttps://wiki.haskell.org/index.php?title=Template:Main/News&diff=2110Template:Main/News2006-01-31T03:19:14Z<p>AudreyTang: </p>
<hr />
<div>* The November 2005 edition of the [http://www.haskell.org/communities/ Haskell Communities and Activities Report] is available now. <br />
*''"Haskell is the programming tool of choice for discriminating hackers"'' for the second year running!<br />The teams winning first and third place in the [http://icfpc.plt-scheme.org/ ICFP 2005 programming contest] both used Haskell.<br />
*[http://www.perl.com/pub/a/2005/03/03/pugs_interview.html An interview with Audrey Tang about her Pugs project] (a Perl 6 implementation in Haskell).<br />
*''"Haskell is the language of choice for discriminating hackers!"''<br>The teams winning first and second place in the [http://www.cis.upenn.edu/proj/plclub/contest/results.php ICFP 2004 programming contest] both used Haskell.<br />
*[[Old news]]</div>AudreyTang