Re: [Haskell-cafe] implementing a csv reader
On Wed, 23 Aug 2006, Robert Dockins wrote: On Aug 23, 2006, at 3:37 PM, Henk-Jan van Tuyl wrote: L.S., Reading and writing a comma seperated datafile doesn't have to be that complicated; the following is an easy way to read a CSV file into a list of tuples and display the list on screen: For every complex problem, there is a solution which is simple, neat, and wrong. -- HL Mencken Although it seems straightforward at first, CSV suffers from text escaping complexities, just as does every other general purpose plain-text encoding. Most notably, a newline embedded inside double quotes does not end a record. I also think that quotes within quotes are represented by rather than \ in CSV. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
On Tue, 2006-08-22 at 11:59 +0200, Tamas K Papp wrote: On Tue, Aug 22, 2006 at 11:26:45AM +0200, Henning Thielemann wrote: See also http://www.xoltar.org/languages/haskell.html http://www.xoltar.org/languages/haskell/CSV.hs Thanks. Haskell is incredibly neat ;-) Now I need to find something else for practice. Is there anything related to data analysis/statistics that is lacking is Haskell? Best, Tamas Maybe a crosstab app? Say, read in some csv data and do a crosstab of it. I was looking at doing one myself quite a while back, but I'm an *ultra-newbie* when it comes to Haskell, and such an app would be a real handful for me... :-) I don't know if it'll help at all (as Python is very different to Haskell) but here's a link to a Python recipe which does this - http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/334695 A Haskell equivalent would (imo) be a *great* example/appetiser for Haskell. Very useful for newbies too, as even for a simple thing like reading data line-by-line, it's really useful to have an easy-to-understand example. A crosstab app mightn't be that easy to _do_, but I think it would be easy to understand. Just my 2c worth ... - Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
L.S., Reading and writing a comma seperated datafile doesn't have to be that complicated; the following is an easy way to read a CSV file into a list of tuples and display the list on screen: displayTuples = do csvData - readFile data.csv putStrLn $ unlines $ map (show . readTuple) $ lines csvData readTuple :: String - (Int, Bool, String) readTuple line = read tuple wheretuple = '(' : line ++ ) If the file data.csv contains the following: 1, True, Festina lente 2, False, Carpe diem displayTuples displays: (1,True,Festina lente) (2,False,Carpe diem) Writing a list of tuples to a CSV file is even simpler: writeTuples file tuples = writeFile file $ unlines $ map (tail . init . show) tuples The call: writeTuples new.csv [(1, 'a'), (2, 'b')] results in a file containg: 1,'a' 2,'b' (without the leading spaces) Met vriendelijke groet, Henk-Jan van Tuyl -- http://Van.Tuyl.eu/ -- On Tue, 22 Aug 2006 11:19:35 +0200, Tamas K Papp [EMAIL PROTECTED] wrote: Hi, Now that I have read the tutorials, I think that the best way to learn Haskell would be to use the language and write something simple yet useful. I noticed that Haskell lacks a module for reading/writing csv (comma separated value) files, so I thought I could implement that. Questions: 1. Please tell me if you know of a csv module, because then I would do something else. 2. I am looking for a parser, but I don't know Haskell parsers. Is Parsec a good choice? Thanks, Tamas -- Using Opera's revolutionary e-mail client: https://secure.bmtmicro.com/opera/buy-opera.html?AID=789433 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
On Aug 23, 2006, at 3:37 PM, Henk-Jan van Tuyl wrote: L.S., Reading and writing a comma seperated datafile doesn't have to be that complicated; the following is an easy way to read a CSV file into a list of tuples and display the list on screen: For every complex problem, there is a solution which is simple, neat, and wrong. -- HL Mencken Although it seems straightforward at first, CSV suffers from text escaping complexities, just as does every other general purpose plain- text encoding. Most notably, a newline embedded inside double quotes does not end a record. These issues cause ugly corner cases if you aren't expecting them. And that's just the issues with moving tables of strings around; if those fields have non-string interpretations (dates or numbers or what have you), things get really hairy. To do the right thing probably requires perl-ish duck typing :-p See http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm for a semi- authoritative reference on CSV. A related RFC is here: http:// tools.ietf.org/html/rfc4180 Rob Dockins Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
On Tue, 22 Aug 2006, Tamas K Papp wrote: Hi, Now that I have read the tutorials, I think that the best way to learn Haskell would be to use the language and write something simple yet useful. I noticed that Haskell lacks a module for reading/writing csv (comma separated value) files, so I thought I could implement that. Questions: 1. Please tell me if you know of a csv module, because then I would do something else. see attachment module Spreadsheet where {- See also http://www.xoltar.org/languages/haskell.html http://www.xoltar.org/languages/haskell/CSV.hs -} import Useful(chop,replace) import Data.List(intersperse) import Text.ParserCombinators.ReadP(ReadP) import qualified Text.ParserCombinators.ReadP as Parser toTable :: Char - Char - String - [[String]] toTable qm sep = let parseChar :: ReadP Char parseChar = Parser.choice [Parser.satisfy (qm/=), Parser.string [qm,qm] return qm] parseQuoted :: ReadP String parseQuoted = Parser.between (Parser.char qm) (Parser.char qm) (Parser.many parseChar) parseCell :: ReadP String parseCell = Parser.choice [parseQuoted, return ] parseLine :: ReadP [String] parseLine = Parser.sepBy (parseCell) (Parser.char sep) parse str = fromSingleton (map fst (filter (null . snd) (Parser.readP_to_S parseLine str))) in map parse . lines fromSingleton :: [a] - a fromSingleton [x] = x fromSingleton [] = error fromSingleton: empty list. fromSingleton _ = error fromSingleton: list must contain at most one element. fromTable :: Char - Char - [[String]] - String fromTable qm sep = unlines . map (concat . intersperse [sep] . map (\s - [qm] ++ replace [qm] [qm,qm] s ++ [qm])) toTableSimple :: Char - Char - String - [[String]] toTableSimple qm sep = map (map (dequote qm) . chop (sep==)) . lines fromTableSimple :: Char - Char - [[String]] - String fromTableSimple qm sep = unlines . map (concat . intersperse [sep] . map (\s - [qm]++s++[qm])) dequote :: Eq a = a - [a] - [a] dequote _ [] = error dequote: string is empty dequote q (x:xs) = if x == q last xs == q then init xs else error dequote: string not correctly quoted ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] implementing a csv reader
Check first MissingH. I remember that it came with some parsing routines for common text formats. Best, Titto -Original Message- From: [EMAIL PROTECTED] [mailto:haskell-cafe- [EMAIL PROTECTED] On Behalf Of Tamas K Papp Sent: 22 August 2006 10:20 To: Haskell Cafe Subject: [Haskell-cafe] implementing a csv reader Hi, Now that I have read the tutorials, I think that the best way to learn Haskell would be to use the language and write something simple yet useful. I noticed that Haskell lacks a module for reading/writing csv (comma separated value) files, so I thought I could implement that. Questions: 1. Please tell me if you know of a csv module, because then I would do something else. 2. I am looking for a parser, but I don't know Haskell parsers. Is Parsec a good choice? Thanks, Tamas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
Hi Tamas, Questions: 1. Please tell me if you know of a csv module, because then I would do something else. I think MissingH contains a simple CSV parser, but the server seems to be down. 2. I am looking for a parser, but I don't know Haskell parsers. Is Parsec a good choice? Parsec is definitely a good choice, but beware that it parses the whole input before returning, thus it may consume a huge batch of memory. As CSV is a line oriented format, you should make your parser lazy. Search the mailing list archive for lazy parser. Regards, Jens ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
On Tue, Aug 22, 2006 at 11:26:45AM +0200, Henning Thielemann wrote: See also http://www.xoltar.org/languages/haskell.html http://www.xoltar.org/languages/haskell/CSV.hs Thanks. Haskell is incredibly neat ;-) Now I need to find something else for practice. Is there anything related to data analysis/statistics that is lacking is Haskell? Best, Tamas ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
Now I need to find something else for practice. How about writing a CiteULike plugin? For example, what could be really useful is if somebody wrote one for the French open archive HAL. This will give you a nice chance to play maybe with parsing stuff, or one of the HTML/XML libraries, or maybe even simple regular expressions. See: http://www.citeulike.org/faq/all.adp http://hal.inria.fr/index.php?langue=en -- Eric Kow http://www.loria.fr/~kow PGP Key ID: 08AC04F9 Merci de corriger mon français. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
Now I need to find something else for practice. Is there anything related to data analysis/statistics that is lacking is Haskell? A native implementation of multiparameter data fitting (requires some linear algebra) like: Sec 15.4 of http://www.library.cornell.edu/nr/bookcpdf.html or http://www.gnu.org/software/gsl/manual/html_node/Multi_002dparameter-fitting.html#Multi_002dparameter-fitting would be nice, unless it exists. (There might be a GSL binding in Haskell for this but I'd rather use a native library.) Jared. -- http://www.updike.org/~jared/ reverse )-: ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] implementing a csv reader
2. I am looking for a parser, but I don't know Haskell parsers. Is Parsec a good choice? Parsec is definitely a good choice, but beware that it parses the whole input before returning, thus it may consume a huge batch of memory. As CSV is a line oriented format, you should make your parser lazy. Search the mailing list archive for lazy parser. A good trick here is to first use lines to break up the input into lines and than map a Parsec parse for each line to those lines (returning a list of Maybe a or ParseError a results). All the best, -- Daan. Regards, Jens ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] implementing a csv reader
On Tue, Aug 22, 2006 at 08:59:40AM -0700, Daan Leijen wrote: 2. I am looking for a parser, but I don't know Haskell parsers. Is Parsec a good choice? Parsec is definitely a good choice, but beware that it parses the whole input before returning, thus it may consume a huge batch of memory. As CSV is a line oriented format, you should make your parser lazy. Search the mailing list archive for lazy parser. A good trick here is to first use lines to break up the input into lines and than map a Parsec parse for each line to those lines (returning a list of Maybe a or ParseError a results). You can also create a lazy many parser using (get|set)ParserState. The benefit is that this will also work if your elements are not in one-to-one relation with lines and that it automatically takes care of maintaining position in the input (for error messages). lazyMany :: GenParser Char () a - SourceName - [Char] - [a] lazyMany p file contents = lm state0 where Right state0 = parse getParserState file contents lm state = case parse p' of Left err - error (show err) Right x - x where p' = do setParserState state choice [ do eof return [] , do x - p state' - getParserState return (x : lm state') ] Best regards Tomasz ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe