[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