HLearn-classification-0.0.1: src/HLearn/DataContainers/CSVParser.hs
module HLearn.DataContainers.CSVParser
( loadCSV
, list2csv
, module Text.ParserCombinators.Parsec
)
where
import System.IO
import Text.ParserCombinators.Parsec
-- | Loads a CSV file. Algorithms store debugging info in CSV files, and this function is used by the plotting routines
loadCSV :: String -> IO (Either ParseError [[String]])
loadCSV filename = do
hin <- openFile filename ReadMode
str <- hGetContents hin
let ds = parseCSV str
return ds
-- | Converts a list into CSV format for writing to a file
list2csv :: [String] -> String
list2csv xs = foldl addcommas "" $ map addquotes xs
where
addcommas x y =
if x==""
then y
else x++","++y
addquotes x = show x
-- list2csv xs = init $ tail $ show xs
-- CSV parser from "Real World Haskell," p. 391
-- modified to allow multiple spaces between cells
parseCSV :: String -> Either ParseError [[String]]
parseCSV input = parse csvFile "(unknown)" input
csvFile = endBy line eol
line = sepBy cell (char ',' <|> char ' ')
cell = do
spaces
quotedCell <|> many (noneOf " ,\n\r")
quotedCell = do
char '"'
content <- many quotedChar
char '"' <?> "Quote at end of cell"
return content
quotedChar = noneOf "\"" <|> try (string "\"\"" >> return '"')
eol = try (string "\n\r")
<|> try (string "\r\n")
<|> try (string "\n")
<|> try (string "\r")
<?> "end of line"
-- test csv parsing
{-
csv_test = do
dm <- loadData $ defDatafileDesc {datafileName="../testdata/ringnorm.data"}
putStrLn $ func dm
where
func (Left x) = show x
func (Right x) = show $ take 10 x-}