
Another newbie question, but I can't seem to find any answers on the web... Can someone tell me what's wrong with this? import qualified System.Posix.Directory as PD 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 alternative indentations (including indenting the "else" more), bracketings etc, but nothing helps. Thanks David -- The Wellcome Trust Sanger Institute is operated by Genome Research Limited, a charity registered in England with number 1021457 and a company registered in England with number 2742969, whose registered office is 215 Euston Road, London, NW1 2BE.

On Nov 1, 2007, at 13:47 , David Carter wrote:
else rest <- readdirAll d
You need another "do" here to use the <- syntax. -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

David Carter wrote:
Another newbie question, but I can't seem to find any answers on the web...
Just figured it out myself ... I need a "do" after the "else", of course. (But I still think the error message is less than helpful!). Sorry for the bandwidth David
Can someone tell me what's wrong with this?
import qualified System.Posix.Directory as PD
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 alternative indentations (including indenting the "else" more), bracketings etc, but nothing helps.
Thanks
David
-- The Wellcome Trust Sanger Institute is operated by Genome Research Limited, a charity registered in England with number 1021457 and a company registered in England with number 2742969, whose registered office is 215 Euston Road, London, NW1 2BE.

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!

(...) Can someone tell me what's wrong with this? import qualified System.Posix.Directory as PD
readdirAll :: PD.DirStream -> IO [String] readdirAll d = do dir <- PD.readDirStream d if dir == "" then return [] else rest <- readdirAll d return (dir:rest) (...)
I don't know if this helps or disturbs, but I wrote a few different versions of your code as an exercise. If you want to try it, just uncomment the versions you want to check. The complete program below lists all files in current directory, using 'readdirAll' to get the full list. Best, Maurício module Main (Main.main) where import qualified System.Posix.Directory as PD import Data.List import Control.Monad main :: IO () readdirAll :: PD.DirStream -> IO [String] readdirAll ds = liftM reverse $ read [] where read ("":t) = return t read list = (PD.readDirStream ds) >>= glue where glue f = read (f:list) {- readdirAll ds = read where read = (PD.readDirStream ds) >>= rest rest "" = return [] rest h = liftM (h:) read -} {- readdirAll ds = do f <- PD.readDirStream ds rest f where rest "" = return [] rest h = return (h:) `ap` (readdirAll ds) -} main = (PD.openDirStream ".") >>= readdirAll >>= (putStrLn.show)
participants (5)
-
Brandon S. Allbery KF8NH
-
David Carter
-
Felipe Lessa
-
Jules Bean
-
Maurício