
Hi, I am relatively new to Haskell and am finding i/o difficult to work with. I am trying to do something like the following: I have a file of data, each line of which looks like this: <STRING>, INTEGER SEQUENCE for example: FOO ,2,1,4,3,6,7,5,9,10,11,8,13,12, I would like to write a function the reads this file and returns arrays like this: ["FOO",[2,1,4,3,6,7,5,9,10,11,8,13,12]] Ideally, the function would return the first line when initially called, the second the next time it is called and so on. I would settle for something that returned a big array comprising arrays of the above type containing all the information in the file. The file is big, however. I can not figure out how to do this from any of the tutorials so I thought I might ask here. Thank you for your help, Robert.

Hi Robert, The first thing to mention is that Haskell uses linked-lists, not arrays as the "standard" list type structure, so [1,2] is actually a linked list. The next thing to note is that Haskell is *lazy*. It won't do work that it doens't have to. This means that you can return a linked list with all the lines in the file, but they won't actually be read til they are required. i.e. Haskell cleverly worries about all the "getting a next line as required" stuff, without you even noticing - it will read it line by line. A simple function that does some of what you want is:
parseFile :: FilePath -> IO [(String, [Int])] parseFile x = do src <- readFile x return (map parseLine (lines src))
parseLine :: String -> (String, [Int]) parseLine = for you to write :)
The other point is that Haskell linked lists have to have every element of the same type, so you can't have ["test",1] as a linked list, what you actually want is a tuple, written ("test",1) - a tuple is of fixed length and all elements can be of different type. Hope that helps, Neil

The other thing to mention, is that if you have the ability to change file formats, it may be better to make just a slight adjustment... If you make it look exactly like the haskell data structure you want: [("Foo", [1,2,3,4,5,6,7]) ,("Bar", [7,6,5,4,3,2,1]) ,...] Then your parser becomes even simpler: parseFile :: FilePath -> IO [(String,[Int])] parseFile = do src <- readFile x return $ read src On Jan 3, 2006, at 11:33 AM, Neil Mitchell wrote:
Hi Robert,
The first thing to mention is that Haskell uses linked-lists, not arrays as the "standard" list type structure, so [1,2] is actually a linked list.
The next thing to note is that Haskell is *lazy*. It won't do work that it doens't have to. This means that you can return a linked list with all the lines in the file, but they won't actually be read til they are required. i.e. Haskell cleverly worries about all the "getting a next line as required" stuff, without you even noticing - it will read it line by line.
A simple function that does some of what you want is:
parseFile :: FilePath -> IO [(String, [Int])] parseFile x = do src <- readFile x return (map parseLine (lines src))
parseLine :: String -> (String, [Int]) parseLine = for you to write :)
The other point is that Haskell linked lists have to have every element of the same type, so you can't have ["test",1] as a linked list, what you actually want is a tuple, written ("test",1) - a tuple is of fixed length and all elements can be of different type.
Hope that helps,
Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Neil and Thomas, Thanks to both of you for your help. I have things working now. Bob
participants (3)
-
Neil Mitchell
-
Robert Heffernan
-
Thomas Davie