I'm trying to learn Haskell by writing little programs... so I'm currently writing a lexer/parser for simple expressions. (Yes I could use Alex/Happy... but I want to learn the core language first).
My parser is essentially a set of recursive functions that build a Tree. In the case of syntax errors, I'd normally throw an exception (i.e. if I were writing in C#), but that seems to be discouraged in Haskell.
So what's the alternative? I don't really want to test for error states in every single bit of the parser. I want to either end up with a valid tree of nodes, or an error state with details.
There are three different kinds of exceptions in Haskell: one is imprecise; two are precise, of which one is synchronous, and one asynchronous. These were all identified in foundational Haskell papers 1.
The Haskell runtime system allows any IO action to throw runtime exceptions. Many common library functions throw runtime exceptions. There is no indication at the type level if something throws an exception. You should assume that, unless explicitly documented otherwise, all actions may throw an exception.
On the one hand, an error is a programming mistake such as a division by zero, the head of an empty list, or a negative index. If we identify an error, we remove it. Thus, we don't handle errors, we simply fix them. In Haskell, we have error and undefined to cause such errors and terminate execution of the program.
Errors are things that can happen, but do not occur intentionally except during testing. Errors occur when something is wrong, but exceptions can occur also when things are correct but need "exceptional" attention. Think of an exception like an interrupt in hardware.
Haskell provides the Maybe
and Either
types for this. Since you want to return an error state, Either
seems to be what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With