
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!