[Haskell-cafe] do/if/then/else confusion
Jules Bean
jules at jellybean.co.uk
Thu Nov 1 17:52:07 EDT 2007
David Carter wrote:
> readdirAll :: PD.DirStream -> IO [String]
> readdirAll d =
> do dir <- PD.readDirStream d
> if dir == ""
> then return []
> else rest <- readdirAll d
> return (dir:rest)
>
> Compiling with GHC 6.6.1 gives me the not-very-useful message "Parse
> error in pattern", pointing to the "i" of "if". I've tried all kinds of
You've worked out the answer, and that's fine. You also said later in
the thread that the error message isn't very good. (Which I agree with)
Perhaps it might help to understand why you do, in fact, get that
strange message. It might illuminate why it's quite so hard to get good
error messages in haskell :-( [*]
When you reach the "i" in "if", ghc knows that you are in a "do"
expression. A "do" expression is a sequence of statements separated by
semicolons (or layout, standing in for semicolons). When we decode the
layout, everything indented further is "part of the same statement". So
in particular, your code parses as
do {
dir <- PD.readDirStream d ;
if dir == "" then return [] else rest <- readdirAll d return (dir:rest);
}
The first statement in the do block is fine.
The second is the problem. Now statements are of two basic forms. They
either have binders, or not. They are either
foo <- expr
or simply
expr
Since the second line contains the magic <-, it must be the former. So
what you have is 'if dir == "" then return [] else rest' being the
'foo', i.e. the bit before the <-.
Now what is *supposed* to come before <- is a pattern (normally a
variable name, which is a simple case of a pattern). "if" is a keyword
which is not permitted to be a variable name or part of a pattern.
Hence "parse error in pattern".
Not sure if that is at all edifying, but it was an interesting exercise
to write it...
Jules
* there are two reasons it's really hard to write a haskell compiler
with good error messages. (1) the layout rule. (2) the use of exotic
type system tricks like type classes to achieve elegant syntax. I don't
mean to say that the developers of haskell compilers shouldn't keep
trying though!
More information about the Haskell-Cafe
mailing list