<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="hugsErrorsStyle.xsl"?>

<!DOCTYPE hugsErrors [
	<!ELEMENT hugsErrors (section)+>
	<!ELEMENT section (item)+>
	<!ELEMENT item (badCode, error, solution)>
	<!ELEMENT badCode (code+ | noCode)>
	<!ELEMENT code (#PCDATA | highlight | space | tab | nl)*>	
	<!ELEMENT error (#PCDATA | highlight | space | tab | nl)*>	
	<!ELEMENT solution (text | error | code)*>	
	<!ELEMENT text (#PCDATA | highlight | nl | tab | inline)*>
	<!ELEMENT inline (#PCDATA)>
	<!ELEMENT highlight (#PCDATA)>
	<!ELEMENT space EMPTY>
	<!ELEMENT tab EMPTY>
	<!ELEMENT nl EMPTY>
	<!ELEMENT noCode EMPTY>
	<!ATTLIST section name (Syntax | Module | Type | Program) #REQUIRED>
	<!ATTLIST item keywords NMTOKENS #IMPLIED>
	<!ATTLIST item id CDATA #IMPLIED>
]>

<hugsErrors>
	<section name="Syntax">
		<item id='1'>
			<badCode>
				<code>3 'div' 4</code>
			</badCode>
     		<error>ERROR: Improperly terminated character constant</error>
			<solution>
				<text>The problem here is the use of the wrong sort of quotes. 
					  To turn a function, which is written before its arguments, 
					  into an operator, which is written between its arguments, 
					  you need to enclose it in backquotes. The backquote is round 
					  on the same key as the tilde on US keyboards (commonly the top 
					  left hand corner of the main block, just above TAB).
				</text>
			</solution>
		</item>
		<item id='2'>
			<badCode>
				<code>data BTree a = EmptyBTree | Node a (BTree a) (BTree a)
					  <nl/><nl/>card :: BTree a -> Integer
					  <nl/>card EmptyBTree = 0
					  <nl/>card (Node x<highlight>)</highlight> lt rt = (height lt) + (height rt) + 1
				</code>
			</badCode>
     		<error>ERROR: Equations give different arities for "card"</error>
			<solution>
				<text>Incorrect bracketing causes the problem here. It looks as though card is a one 
					  argument function (arity 1) from the first equation in the definition, and as 
					  though it's a three argument function from the second. The misplaced closing 
					  bracket is the culprit, and a correct version of the code says
				</text>
				<code>card (Node x lt rt<highlight>)</highlight> = (height lt) + (height rt) + 1</code>
			</solution>
		</item>
		<item id='3'>
			<badCode>
				<code>><tab/>maxFour :: Int -> Int -> Int -> Int -> Int
					  <nl/>><tab/><highlight>maxFour</highlight>
					  <nl/>><tab/><tab/>| a >= b &amp;&amp; a >= c &amp;&amp; a >= d <space/>= a
					  <nl/>><tab/><tab/>| b >= c &amp;&amp; b >= d<tab/><tab/><tab/>= b
					  <nl/>><tab/><tab/>| c >= d <tab/><tab/><tab/><tab/><tab/> = c
					  <nl/>><tab/><tab/>| otherwise <tab/><tab/><tab/><tab/><space/> = d
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 3): Undefined variable "a"</error>
			<solution>
				<text>
					The definition of maxFour has its variables missing. The second line should read<inline> maxFour a b c d.</inline>
				</text>
			</solution>
		</item>
		<item id='4'>
			<badCode>
				<code>><tab/>exOr :: <highlight>bool -> bool -> bool</highlight>
					  <nl/>><tab/>exOr b1 b2
					  <nl/>><tab/><tab/>= (b1 &amp;&amp; not b2) || (b2 &amp;&amp; not b1)
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 3): Declared type too general
     			<nl/>*** Expression<tab/>: exOr
     			<nl/>*** Declared type : a -> a -> a
				<nl/>*** Inferred type : Bool -> Bool -> Bool
     		</error>
			<solution>
				<text>The problem here is with the bools in the type. The Boolean type 
					  is written Bool and so the first line should read 
				</text>
				<code>exOr :: Bool -> Bool -> Bool</code>
				<text>What does the error message mean? The bool is taken to be a type 
					  variable, and so the declaration asserts that the function has a 
					  polymorphic type (which of course it doesn't). 
				</text>
			</solution>
		</item>
		<item id='5'>
			<badCode>
				<code>><tab/>ex = (2==3))</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Syntax error in input (unexpected `)')</error>
			<solution>
				<text>The presence of an extra closing parenthesis is signalled as an unexpected 
					  piece of input. Other `unexpected' symbols can be more enigmatic.... 
				</text>
			</solution>
		</item>
		<item id='6'>
			<badCode>
				<code>><tab/>fun x
				      <nl/>><tab/>fun 2 = 34
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Syntax error in input (unexpected `;')</error>
			<solution>
				<text>The problem here is that the first line is incomplete. Formatting means 
					  that the symbol fun in the second line signals by layout that the construct 
					  in the first line is finished. The explicit Haskell symbol for the end of 
					  a construct is `;'; hence the message.
					  <nl/><nl/>Another peculiarity of the system is given by
				</text>
				<code>><tab/>fun x
				      <nl/>><tab/> fun 2 = 34
				</code>
				<text>which is not erroneous. It means the same as</text>
				<code>><tab/>fun x y 2 = 34</code>
				<text>because the second use of fun is treated as a variable!</text>
			</solution>
		</item>
		<item id='7'>
			<badCode>
				<code>><tab/>module Junk where
					  <nl/>>
					  <nl/>><tab/>a = (True, [1,2,3,4]
				</code>
			</badCode>
     		<error>ERROR "Junk.lhs" (line 4): Syntax error in expression (unexpected `}')</error>
			<solution>
				<text>This problem happens because there is a closing bracket missing at the end of 
					  the line. The } symbol is used to group definitions together, and also to define 
					  records with named fields. An error like this occurs when grouping is incorrect 
					  or, if you are using records, in record syntax. 
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>f :: Int -> [Int] -> [Int]
					  <nl/>><tab/>f a x = (a:x
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 4): Syntax error in expression (unexpected `}', possibly due to bad layout)</error>
			<solution>
				<text>The problem here is not so much bad layout as a missing closing parenthesis!</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x = 17
					  <nl/>><tab/><space/>type Fred = Int
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")</error>
			<solution>
				<text>This problem happens because of the indentation of the second line is incorrect; 
					  it should be indented to the same level as the first line.
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/><space/>fun x = 17
					  <nl/>><tab/>type Fred = Int
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")</error>
			<solution>
				<text>This problem happens because of the indentation of the second line is incorrect; 
					  it should be indented to the same level as the first line.
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>Fun x = 17</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Undefined constructor function "Fun"</error>
			<solution>
				<text>The syntax of the language dictates that names for functions and other 
					  defined values begin with a small letter. Names beginning with capitals 
					  are reserved for constructors (of <inline>data</inline> types) and for types and type 
					  classes. Here the use of a capital letter in <inline>Fun</inline> is seen to be the use 
					  of a constructor which is not defined. 
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x = 17
					  <nl/>><tab/><tab/>where
					  <nl/>><tab/><tab/>type Fun = Int
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Syntax error in input (unexpected keyword "type")</error>
			<solution>
				<text>The problem here is that type definitions are not allowed in where clauses.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x x = 17</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Repeated variable "x" in pattern</error>
			<solution>
				<text>A variable can only occur once on the left-hand side of a definition. You can get the same effect with</text>
				<code>><tab/>fun x y
					  <nl/>><tab/><tab/>| x==y = 17
				</code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>double - 4</code>
			</badCode>
     		<error>ERROR: Illegal Haskell 98 class constraint in inferred type
     			   <nl/>*** Expression : double - 4
     			   <nl/>*** Type<tab/><space/><space/><space/>: Num (Int -> Int) => Int -> Int
     		</error>
			<solution>
				<text>where <inline>double</inline> is of type <inline>Int -> Int</inline>. The problem is that -4 needs 
					  to be parenthesised, as in <inline>double (-4)</inline>.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x = x + abs -2</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): a -> a is not an instance of class "Num"</error>
			<solution>
				<text>In the definition here, the function <inline>abs</inline> is supposed to be applied to <inline>-2</inline>; 
					  what happens instead is that <inline>2</inline> is subtracted from the function <inline>abs</inline>.
					  <nl/><nl/>Negative literals need to be enclosed in parentheses, as in
				</text>
				<code>><tab/>fun x = x + abs (-2)</code>
				<text>In Hugs98 a different error message is generated by the same script.</text>
				<error>ERROR "text.lhs" (line 1): Illegal Haskell 98 class constraint in inferred type
					   <nl/>*** Expression : fun
					   <nl/>*** Type<tab/><space/><space/><space/>: (Num (a -> a), Num a) => (a -> a) -> a -> a
				</error>
			</solution>
		</item>
		<item>
			<badCode>
				<code>Are two integers in ascending order?
					  <nl/><nl/>><tab/>ascendingOrder :: Int -> Int -> Bool
					  <nl/>><tab/>ascendingOrder x y = (x&lt;=y)
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Program line next to comment</error>
			<solution>
				<text>The message here is slightly misleading: the program line is 
					  immediately below a comment, and that is not acceptable syntax. 
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>test :: (Bool,Bool) -> Bool
				<nl/>><tab/>test (b1,<highlight>2b</highlight>) = b1</code>
			</badCode>
     		<error>"test.lhs" (line 2): Illegal pattern syntax</error>
			<solution>
				<text>The illegality is to have mistyped <inline>b2</inline> as <inline>2b</inline>.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>predecessor <highlight>n</highlight> :: Num a => a -> a
					  <nl/>><tab/>predecessor n
					  <nl/>><tab/><tab/>| n>0 = n-1
					  <nl/>><tab/><tab/>| n==0 = 0
				</code>
			</badCode>
     		<error>Syntax error in input (unexpected `|')</error>
			<solution>
				<text>The problem here is the argument n which appears in the type declaration. This should read:</text>
				<code>><tab/>predecessor :: Num a => a -> a
				</code>
				<text>which states that the type of the predecessor function is <inline>a -> a</inline> for any type
					  <inline>a</inline>in the <inline>Num</inline> class. </text>
			</solution>
		</item>
	</section>
	<section name="Module">
		<item>
			<badCode>
				<code>><tab/>Any Haskell code in literate form</code>
			</badCode>
     		<error>ERROR "test.hs" (line 3): Syntax error in input (unexpected symbol ">")</error>
			<solution>
				<text>This is due to having a literate script in a <inline>.hs</inline> file.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>Any Haskell code in non-literate form</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 8): Empty script - perhaps you forgot the `>'s?</error>
			<solution>
				<text>As the message implies, this results from having a non-literate script in a <inline>.lhs</inline> file.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fred :: Int -> Int</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Missing binding for variable "fred" in type signature</error>
			<solution>
				<text>The problem here is that the function <inline>fred</inline> has its type declared, 
					  but it is not actually defined in the module.
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>elem :: Int -> [Int] -> Bool
					  <nl/>><tab/>elem x xs = [y | y&lt;-xs, y==x] /= []
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Definition of variable "elem" clashes with import</error>
			<solution>
				<text>This definition re-defines something imported from the standard <inline>Prelude.</inline> 
					  It can be hidden on import by including the import statement 
				</text>
				<code>><tab/>import Prelude hiding (elem)</code>
				<text>at the start of the module.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code></code>
			</badCode>
     		<error>ERROR "File2.lhs": Module "Main" already loaded</error>
			<solution>
				<text>This error happens if you load two anonymous modules into (Win)Hugs. The solution is 
					  to name the modules concerned and to set up the appropriate import/export structures.  
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>f [] = 23
					  <nl/><nl/>><tab/>g y = 2
					  <nl/><nl/>><tab/><highlight>f (x:xs) = 6</highlight>
				</code>
			</badCode>
     		<error>ERROR "test.hs" (line 2): "f" multiply defined</error>
			<solution>
				<text>The first line of the file defines the function f, and the second the function g; the third, erroneously, 
					  adds another clause of the definition of f. This is an error. This could happen by inserting by mistake 
					  a section into an existing definition. 
				</text>
			</solution>
		</item>
	</section>
	<section name="Type">
		<item>
			<badCode>
				<code>><tab/>foo :: Int -> [Char]
					  <nl/>><tab/>foo x = ['1'] ++ foo(x <highlight>div</highlight> 10)
				</code>
			</badCode>
     		<error>*** term <tab/><tab/><space/><space/>: foo
     			   <nl/>*** type <tab/><tab/><space/><space/>: ((a -> a -> a) -> b -> Int) -> [Char]
     			   <nl/>*** does not match : Int -> [Char]
     		</error>
			<solution>
				<text>The intention here was to divide the numerical input x by 10; <inline>div</inline> 
					  should have appeared in back-quotes: <inline>`div`</inline>. The program is a correct 
					  program, in which x is applied to the function <inline>div</inline>, hence the error 
					  appears as a mis-typing. This is a good example of why it is sensible 
					  to include type declarations in definitions; if the declaration was missing, 
					  the <inline>foo</inline> function would be accepted, only to be rejected (presumably) at 
					  the first point at which it is used. 
				</text>
			</solution>
		</item>	
		<item id="102">
			<badCode>
				<code>empty :: [a] -> Bool
					  <nl/>empty as = (as == [])
				</code>
			</badCode>
     		<error>ERROR "test.hs" (line 2): Cannot justify constraints in explicitly
     			   <nl/>typed binding
     			   <nl/>*** Expression<tab/>: empty
     			   <nl/>*** Type<tab/><tab/><space/><space/>: [a] -> Bool
     			   <nl/>*** Given context : ()
     			   <nl/>*** Constraints<space/><space/> : Eq a
     		</error>
			<solution>
				<text>The problem here is that in order to compare lists for equality one 
					  can only do this when the elements themselves carry an equality function. 
					  This is necessary even when comparing with the empty list. It is fixed thus 
				</text>
				<code>empty :: Eq a => [a] -> Bool
					  <nl/>empty as = (as == [])
				</code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>compress :: [a] -> [a]
					  <nl/>><tab/>compress [] = []
					  <nl/>><tab/>compress [a] = [a]
					  <nl/>><tab/>compress (x:y:xs)
					  <nl/>><tab/><tab/>| (x <highlight>==</highlight> y) <space/>= compress (x:xs)
					  <nl/>><tab/><tab/>| otherwise = x : compress (y:xs)
				</code>
			</badCode>
     		<error>ERROR "lab2.hs" (line 2): Cannot justify constraints in explicitly typed binding
     			   <nl/>*** Expression<tab/>: compress
     			   <nl/>*** Type <tab/><tab/> : [a] -> [a]
     			   <nl/>*** Given context : ()
     			   <nl/>*** Constraints <space/> : Eq a
     		</error>
			<solution>
				<text>The problem here is that the equality function, ==, is used over the elements 
					  of the list. This needs to be acknowedged in the type of the function, making 
					  it include the constraint that the type a belongs to the equality class, <inline>Eq</inline>, 
				</text>
				<code>><tab/>compress ::  Eq a => [a] -> [a]</code>
			</solution>
		</item>	
		<item keywords='blob one two'>
			<badCode>
				<code>><tab/>ascendingOrder :: Int -> Int -> Bool
					  <nl/>><tab/>ascendingOrder a b
					  <nl/>><tab/><tab/>| a&lt;=b <tab/> = <highlight>a b</highlight>
					  <nl/>><tab/><tab/>| otherwise = <highlight>b a</highlight>
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 3): Type error in application
     			   <nl/>*** expression<tab/> : a b
     			   <nl/>*** term <space/><tab/><tab/> : b
     			   <nl/>*** type <space/><tab/><tab/> : a -> b
     			   <nl/>*** does not match : a
     			   <nl/>*** because<tab/><tab/>: unification would give infinite type
     		</error>
			<solution>
				<text>The function here should return a Boolean indicating whether 
					  its two arguments, <inline>a</inline> and <inline>b</inline> are in ascending order.
					  <nl/><nl/>Instead the function attempts to return the two ``in ascending order''. 
					  Looking at the definition, in the third line <inline>a</inline> is applied to <inline>b</inline>, 
					  so <inline>a</inline> must be a function which can be applied to <inline>b</inline>. On the other 
					  hand, in line 4 the reverse happens, so <inline>b</inline> is applied to a. Trying to resolve 
					  these two constraints gives rise to the ``infinite type'' in the error message.
					  <nl/><nl/>The problem here is compounded here by using <inline>a</inline>, <inline>b</inline> 
					  and so on as variable names, since the system uses them also as type variable names. Rewriting 
					  the function to use <inline>x</inline>, <inline>y</inline> etc. as variables helps to make the 
					  error message more comprehensible: 
				</text>
				<code>><tab/>ascendingOrder :: Int -> Int -> Bool
					  <nl/>><tab/>ascendingOrder x y
					  <nl/>><tab/><tab/>| x&lt;=y <tab/> = x y
					  <nl/>><tab/><tab/>| otherwise = y x
				</code>
			    <error>ERROR "test.lhs" (line 3): Type error in application
     				<nl/>*** expression<tab/> : x y
    	 			<nl/>*** term <space/><tab/><tab/> : y
	     			<nl/>*** type <space/><tab/><tab/> : a -> b
     				<nl/>*** does not match : a
     				<nl/>*** because<tab/><tab/>: unification would give infinite type
     			</error>			
			</solution>			
		</item>
		<item>
			<badCode>
				<code>><tab/>ex = [('2',2),('1',<highlight>'1'</highlight>),('a',3)]</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Char is not an instance of class "Num"</error>
			<solution>
				<text>The problem here is that a character '1' is being used in a place where a number should appear.
					  <nl/>This error message refers to the class system in Haskell; if you don't know about this, then you 
					  can still get some useful information from the error message, namely
					  <nl/><nl/><tab/>- the error occurs on line 1;
					  <nl/><nl/><tab/>- a character is being used when something else is expected;
					  <nl/><nl/><tab/>- the name of the class mentioned, Num, suggests that a number was expected.
					  <nl/><nl/>In general, an error containing <inline>Blah is not an instance of class "Plonk"</inline> 
					  indicates that something of type <inline>Blah</inline> appears (on the line in question) in a place 
					  where something related to <inline>Plonk</inline> was expected. 
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x = x ++ <highlight>2</highlight></code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): Illegal class constraint Num (a b) in inferred type.</error>
			<solution>
				<text>The operator <inline>++</inline> needs to be applied to lists; here it is applied to (a list and) a number. The right-hand side is fixed thus: <inline>x ++ [2].</inline></text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>convert :: String -> String
					  <nl/>><tab/>convert s = "Co" ++ (<highlight>300 +</highlight> tail s)
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Instance of Num [Char] required for definition of convert</error>
			<solution>
				<text>A problem here is the use of <inline>+</inline> to join a number to a string; the compiler therefore tries to find a definition of <inline>+</inline> over string, i.e. <inline>[Char]</inline> and fails. </text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun x = <highlight>[2]</highlight>:[2]</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 1): [a] is not an instance of class "Num"</error>
			<solution>
				<text>Here a list is being added to the front of a list of numbers; a list is used where a number is expected.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>myCheck :: <highlight>Int</highlight> -> Bool
					  <nl/>><tab/>myCheck n = ord n == 6
				</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 2): Type error in function binding
     			   <nl/>*** term <tab/><tab/><space/> : myCheck
     			   <nl/>*** type <tab/><tab/><space/> : Char -> Bool
     			   <nl/>*** does not match : Int -> Bool
     		</error>
			<solution>
				<text>The problem here is that an incorrect type is specified for 
					  a correct definition. The type assertion needs to be replaced by
				</text>
				<code>><tab/>myCheck :: Char -> Bool</code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>type Fred = (<highlight>Fred</highlight>,Int)</code>
			</badCode>
     		<error>ERROR "test.lhs" (line 11): Recursive type synonym "Fred"</error>
			<solution>
				<text>Only types defined using data can be recursive. The intended effect is given by</text>
				<code>><tab/>data Fred = Fred Fred Int</code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>proximity :: a -> a -> Double
				<nl/>><tab/>proximity x y = 0
				<nl/><nl/>><tab/>q :: b -> Int
				<nl/>><tab/>q p = 0
				<nl/>><tab/><tab/>where
				<nl/>><tab/><tab/><highlight>g :: b -> Double</highlight>
				<nl/>><tab/><tab/>g = proximity p</code>
			</badCode>
     		<error>Type checking
     			   <nl/>ERROR "test.hs" (line 8): Inferred type is not general enough
     			   <nl/>*** Expression<tab/> : g
     			   <nl/>*** Expected type : a -> Double
     			   <nl/>*** Inferred type : _2 -> Double
     		</error>
			<solution>
				<text>The problem here is the type declaration <inline>g :: b -> Double</inline> in 
					  the local definition: without this, the code type checks. What is the difficulty? 
					  It is in the interpretation of a statement like <inline>g :: b -> Double</inline>, 
					  which means that <inline>g</inline> can be passed an argument of any type. The problem 
					  is that this isn't the role of <inline>g</inline> here: this function can only receive 
					  an element of whatever <inline>q</inline> is passed. The type of <inline>g</inline> 
					  can only be expressed correctly in the presence of scoped type variables: we need the 
					  <inline>b</inline> in <inline>q :: b -> Int</inline> to be usable (in scope) throughout 
					  the definition of <inline>q</inline> rather than just in the type declaration itself, 
					  as is the case in the current language definition. </text>
			</solution>
		</item>
	</section>
	<section name="Program">
		<item>
			<badCode>
				<code>3/0</code>
			</badCode>
     		<error>Program error: {primDivDouble 3.0 0.0}</error>
			<solution>
				<text>Here a number is being divided by zero: the `primitive' function, <inline>primDivDouble</inline>, 
					  causes an error when being trying to divide by zero. Exactly the same error message is given by 
					  evaluating 
				</text>
				<code>(1+2)/0</code>
				<text>showing that the error message shows the values for which the division is called, rather than the 
					  expressions which have those values.
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun n = fun (n+1)</code>
			</badCode>
     		<error>Segmentation Fault (core dumped)</error>
			<solution>
				<text>Evaluating <inline>fun 1</inline> initiates a recursion that carries 
					  on indefinitely: the Hugs system (on Unix) crashes with this classic error message!
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>fun n = fun (n+1)</code>
			</badCode>
     		<error>ERROR: Control stack overflow</error>
			<solution>
				<text>If you try to evaluate <inline>fun 1</inline>: the recursion calls 
					  <inline>fun 2</inline>, which calls <inline>fun 3</inline> and so on.... 
					  This never gives an answer, but rather goes on forever; after some time it overruns the 
					  `control stack' which causes the message that you saw. 
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>[1 .. 10]!!23</code>
			</badCode>
     		<error>Program error: PreludeList.!!: index too large</error>
			<solution>
				<text>This error message is helpful. It indicates the function causing the problem, 
					  namely the !! function from the <inline>PreludeList</inline> module; qualified naming is being 
					  used here. The error message itself is contained in the error call in the definition of the !! 
					  function in <inline>PreludeList</inline>:
					  <nl/><nl/><tab/><inline>...</inline>
				</text>
				<code>[] !! _ = error "PreludeList.!!: index too large"</code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>concat [1,2,3]</code>
			</badCode>
     		<error>ERROR: Illegal class constraint Num (a b) in inferred type.</error>
			<solution>
				<text>This is a type error(!): <inline>concat</inline> expects a list of lists, but 
					  is instead passed a list of numbers. The problem here is that -- in Hugs 1.4, 
					  at least -- concat is overloaded to work over all monads (which generalise lists) 
					  and this gives rise to this kind of error. This should not be a problem in 
					  implementations of Haskell 98. Assuming that 
				</text>
				<code>concat :: [[a]] -> [a]</code>
				<text>the error message generated for <inline>concat [1,2,3]</inline> will be </text>
				<error>ERROR: [a] is not an instance of class "Num"</error>
			</solution>
		</item>
		<item>
			<badCode>
				<code>><tab/>test :: [Bool] -> [Bool]
				<nl/>><tab/>test [] = [False]
				<nl/><nl/>test [True]</code>
			</badCode>
     		<error>Program error: {<highlight>test [True]</highlight>}</error>
			<solution>
				<text>This error message here is less helpful. It indicates that an error is caused by applying <inline>test</inline> to the list <inline>[True]</inline>, but fails to say that this is due to a missing pattern. An alternative definition</text>
				<code>><tab/>test xs = case xs of > [] -> [False]</code><text>provokes the message</text>
				<error>Program error: {test_v850 [False]}</error><text>showing that an error occurs in a pattern match somewhere inside the function test. At worst, a missing pattern can give rise to the message</text>
				<error>Program error: {_FAIL}</error><text>A similar problem is produced by</text><code>totalArea :: [(Float,Float)] -> [(Float)]<nl/>totalArea <highlight>[(a,b)]</highlight> = map times2 [(a,b)]</code>
				<code>times2 :: (Float,Float) -> Float<nl/>times2 (a,b) = a * b</code><text>Here the difficulty is that totalArea is only defined over lists of pairs which contain exactly one element. Replacing the argument [(a,b)] with a variable does the trick.</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code>reverse []</code>
			</badCode>
     		<error>ERROR: Cannot find "show" function for:
     			   <nl/>*** expression <space/>: reverse []
     			   <nl/>*** of type <tab/>: [a]
     		</error>
			<solution>
				<text>The top-level system for Hugs can only print values which belong to a type which can be shown, 
					  that is a type which belongs to the <inline>Show</inline> class. Now, the list type is an instance 
					  of  <inline>Show</inline>, so what is wrong with <inline>reverse []</inline> (which evaluates to [])? 
					  The problem is that the type of [] is polymorphic: <inline>[] :: [a]</inline> for all <inline>a</inline>. 
					  Not knowing a Hugs refuses to print a value of type <inline>[a]</inline>. Note that this behaviour 
					  applies to all polymorphic values. Given the definition 
				</text>
				<code>data Tree a = Empty | Node (Tree a) a (Tree a)</code>
				<text>we have, on evaluating</text>
				<code>Empty</code>
				<text>the error message</text>
				<error>ERROR: Cannot find "show" function for:
					   <nl/>*** expression <space/>: Empty 
					   <nl/>*** of type <tab/>: Tree a
				</error>
				<text>Functions can be shown, but not very helpfully; printing any function results in
				</text>
				<code>&lt;&lt;function>></code>
			</solution>
		</item>
		<item>
			<badCode>
				<code>(1,2,3,4,5,6)</code>
			</badCode>
     		<error>ERROR: Cannot find "show" function for:
     			   <nl/>*** Expression <space/>: (1,2,3,4,5,6)
				   <nl/>*** Of type<tab/> : (Integer,Integer,Integer,Integer,Integer,Integer)
     		</error>
			<solution>
				<text>The Hugs system derives show functions, which convert values into <inline>Strings</inline>, 
					  for various types automatically, and uses these functions in printing out values. Unfortunately, 
					  it will only derive show functions for tuples with five or fewer components.
				</text>
			</solution>
		</item>
		<item>
			<badCode>
				<code></code>
			</badCode>
     		<error>ERROR: Garbage collection fails to reclaim sufficient space
     		</error>
			<solution>
				<text>This occurs during or after evaluation of a large expression; 
					  it means that the heap for Hugs is too small. Heap size can be 
					  changed; consult the documentation; use :set to find the current size. 
				</text>
			</solution>
		</item>
	</section>
</hugsErrors>

