views:

185

answers:

2

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.

+9  A: 

Haskell provides the Maybe and Either types for this. Since you want to return an error state, Either seems to be what you want.

Paul
+5  A: 

For a computation that might fail with details on why it failes, there's the type Either a b, e.g. Either ErrorDetails ParseTree, so your result could be Right theParseTree or Left ErrorDetails. You can pattern-match these constructors in your recursive function and if there's an error, you pass it on; otherwise you go on as usual.

delnan
Larger Haskell programs hide these details by making `instance Monad (Either ErrorDetails) where ...` so you don't have to explicitly handle the error case in each function.
TomMD
@TomMD: Yes, but you don't suggest "make you own monad" to a new learner ;)
delnan
TomMD
@TomMD: Don't get me wrong, people should certainly learn about Monads etc but odds are that going into depth before the rest of the language is understood will just confuse them or scare them off.
delnan
Writing an explicit version of error threading is one of the nicest possible ways to learn exactly why monads are so useful to begin with.
sclv
@sclv, your comment is worth at least +2.
John
@delnan - IMO TomMDs tip is useful in a "don't worry about it yet, but you'll find out how to handle things more neatly later" kind of way. With Haskell being so different to most languages, occasional reminders that most of the WTF-ness will go away are a good thing. The WTF-ness in same-as-you're-used-to languages is expected and ignored, whereas even the most illusory WTF-ness in a very different language is attention-grabbing and can easily be demotivating.
Steve314
BTW, `Control.Monad.Error` provides a monad instance for `Either String a`, where `fail "foo" == Left "foo"` and `return foo == Right foo`.
FUZxxl
Cheers everyone, interesting discussion. I think I'll follow @sclv's advice first and write it in the way I imagined, and then it looks like I need to understand monads, and I'll try to then convert my original into that form (whatever that might be).
stusmith