
Hi With the following program: --------------------------------- import System main = do (x:_) <- getArgs print $ fact (read x) fact :: Int -> Int fact 0 = 1 fact n | n > 0 = n * fact (n - 1) -------------------------------- Running Main without any arguments via Hat gives me a trace, and the error message:
Error: pattern-match failure in do expression
Running hat-stack Main.hat gives me:
Tracefile "Main.hat" contains no reference to a program error.
How come? I get the same results on both Windows and Linux. Thanks Neil

"Neil Mitchell"
Running Main without any arguments via Hat gives me a trace, and the error message:
Error: pattern-match failure in do expression
Running hat-stack Main.hat gives me:
Tracefile "Main.hat" contains no reference to a program error.
Very strange. The tracefile contains the error message (at the end), and an explicit reference to it (in bytes 8-11). But it contains no reference (in bytes 4-7) to the expression that triggered the error, and so hat-stack quite reasonably complains. It looks like the library code to trap the error and tidy up the tracefile might have a bug. Regards, Malcolm

I can explain this. A pattern match failure in a "do" will call "fail" (not "error" as other pattern match failures do). This is the "fail" of the IO monad, which calls "ioError". And "ioError" raises an exception. This exception is caught by a "catch" that Hat has put around "main" and that records the exception in the trace file and terminates the computation. However, for raising and catching an exception the standard Haskell functions are used, so no information about which expression raised the exception is actually passed to the "catch" around main. That's why it cannot write anything about the origin of the exception in the trace. An idea that comes to my mind is that every expression raising an exception could record itself in a global variable in C land. So when the outermost "catch" catches an exception, it can read the origin from this global variable. There is no problem with normal "catch" functions in user programs. It just isn't very nice and it wouldn't work with concurrency. Hat currently doesn't work with concurrency, but I believe currently concurrency could be done in principle by removing the shadow stack, which is only there for optimisation, but not strictly necessary. I cannot think of any solution that would deal with exceptions and work with concurrency. Any suggestions? Ciao, Olaf Malcolm Wallace wrote:
"Neil Mitchell"
wrote: Running Main without any arguments via Hat gives me a trace, and the error message:
Error: pattern-match failure in do expression
Running hat-stack Main.hat gives me:
Tracefile "Main.hat" contains no reference to a program error.
Very strange. The tracefile contains the error message (at the end), and an explicit reference to it (in bytes 8-11). But it contains no reference (in bytes 4-7) to the expression that triggered the error, and so hat-stack quite reasonably complains.
It looks like the library code to trap the error and tidy up the tracefile might have a bug.
Regards, Malcolm _______________________________________________ Hat mailing list Hat@haskell.org http://www.haskell.org/mailman/listinfo/hat

Hi,
A pattern match failure in a "do" will call "fail" (not "error" as other pattern match failures do). This is the "fail" of the IO monad, which calls "ioError".
I believe according to Haskell 98, fail in the IO monad calls error - its only recent extension to GHC/Hugs which have resulted in ioError and exceptions. Perhaps for the purposes of hat stuff, error should be called instead? At least until a proper exception story can be developed. Thanks Neil

"Neil Mitchell"
A pattern match failure in a "do" will call "fail" (not "error" as other pattern match failures do). This is the "fail" of the IO monad, which calls "ioError".
I believe according to Haskell 98, fail in the IO monad calls error - its only recent extension to GHC/Hugs which have resulted in ioError and exceptions. Perhaps for the purposes of hat stuff, error should be called instead? At least until a proper exception story can be developed.
The problem is, that would require type information about which monad the 'do' block belongs to. For IO, it might be fine for a pattern-match failure to call 'error', but it would be totally incorrect for, say, the Maybe monad, or the list monad, where fail might be defined as e.g. 'const Nothing' or 'const []'. Regards, Malcolm

Neil Mitchell wrote:
Hi,
A pattern match failure in a "do" will call "fail" (not "error" as other pattern match failures do). This is the "fail" of the IO monad, which calls "ioError".
I believe according to Haskell 98, fail in the IO monad calls error - its only recent extension to GHC/Hugs which have resulted in ioError and exceptions. Perhaps for the purposes of hat stuff, error should be called instead? At least until a proper exception story can be developed.
From the Haskell 98 report: The fail method of the IO instance of the Monad class (Section 6.3.6 http://haskell.org/onlinereport/basic.html#monad-class) raises a userError, thus: instance Monad IO where ...bindings for return, (>>=), (>>) fail s = ioError (userError s) Also other IO operations (e.g. file not found) will directly raise an exception. Ciao, Olaf
participants (3)
-
Malcolm Wallace
-
Neil Mitchell
-
Olaf Chitil