Skip to content

Instantly share code, notes, and snippets.

@melrief
Created November 25, 2013 10:26
Show Gist options
  • Save melrief/7639339 to your computer and use it in GitHub Desktop.
Save melrief/7639339 to your computer and use it in GitHub Desktop.
Create a list of strings from a CSV line. Requires the DList library installed. Usage example: ghc csv.hs; ./csv 'foo,bar,"foo,bar","foo bar "" foo,,bar",bar'
import Control.Monad (forM_)
import qualified Data.DList as DL
import System.Environment (getArgs,getProgName)
import System.Exit (exitSuccess)
data CSVState = OutsideQuote | InsideQuote | AfterQuote
listFromCSV :: String
→ [String]
listFromCSV = toResult ∘ foldl parseChar (OutsideQuote,DL.empty,DL.empty)
where
parseChar (OutsideQuote,res,curr) ',' = (OutsideQuote,snocBS res curr,DL.empty)
parseChar (OutsideQuote,res,curr) '"' = (InsideQuote,res,curr)
parseChar (OutsideQuote,res,curr) c = (OutsideQuote,res,DL.snoc curr c)
parseChar (InsideQuote ,res,curr) '"' = (AfterQuote,res,curr)
parseChar (InsideQuote ,res,curr) c = (InsideQuote,res,DL.snoc curr c)
parseChar (AfterQuote ,res,curr) '"' = (InsideQuote,res,DL.snoc curr '"')
parseChar (AfterQuote ,res,curr) ',' = (OutsideQuote,snocBS res curr,DL.empty)
parseChar (AfterQuote ,res,curr) c = (OutsideQuote,res,DL.snoc curr c)
toResult :: (CSVState,DL.DList String,DL.DList Char) → [String]
toResult = DL.toList ∘ addLast
addLast (_,res,curr) = snocBS res curr
snocBS dl b = DL.snoc dl (DL.toList b)
main :: IO 𐌏
main = do
args ← getArgs
if null args
then do
progName ← getProgName
putStrLn $ "Usage: " ++ progName ++ " <csv_string> [<csv_string>...]"
else do
forM_ args $ λarg → do
let csv = listFromCSV arg
putStrLn $ show arg ++ " ⇒ " ++ show csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment