Title

Saturday, 17 January 2015

how to parse yahoo csv with parsec


how to parse into array such as open[i],high[i],low[i],close[i]

testhaskell.hs:22:5:   Couldn't match type `[]' with `IO'   Expected type: IO a0   Actual type: [a0]   In the return type of a call of `map'   In a stmt of a 'do' block: map (\ line -> sentence line) allLines   In the expression:   do { handle <- openFile   "C:\\Users\\ivan\\Downloads\\0388.HK.csv" ReadMode;     contents <- hGetContents handle;   let allLines = lines contents;   map (\ line -> sentence line) allLines;   .... }    testhaskell.hs:22:19:   Couldn't match expected type `String -> a0'   with actual type `Text.Parsec.Prim.ParsecT   String () Data.Functor.Identity.Identity [String]'

import System.IO  import qualified Data.ByteString.Char8 as BS  import qualified Data.ByteString as Str  import Text.ParserCombinators.Parsec    word :: Parser String  word = many1 letter    sentence :: Parser [String]  sentence = do{ words <- sepBy1 word separator   ; oneOf ".?!" <?> "end of sentence"   ; return words   }    separator :: Parser ()  separator = skipMany1 (space <|> char ',' <?> "")    main = do   handle <- openFile "C:\\Users\\ivan\\Downloads\\0005.HK.csv" ReadMode   contents <- hGetContents handle   let allLines = lines contents   map (\line -> sentence line) allLines   --putStr contents    hClose handle

update:

module Main where    import qualified Data.ByteString.Char8 as B  import Data.Map ((!))  import Data.Text  import qualified Data.Vector as V  import System.Directory  import Test.Framework (Test, defaultMain, testGroup)  import Test.Framework.Providers.API  import Test.HUnit ((@=?))    import Data.CSV.Conduit      main :: IO ()  main = defaultMain tests      tests :: [Test]  tests = [testGroup "Basic Ops" baseTests]      baseTests :: [Test]  baseTests =   [   testCase "simple parsing works" test_simpleParse   ]      test_simpleParse :: IO ()  test_simpleParse = do   (d :: V.Vector (MapRow B.ByteString)) <- readCSVFile csvSettings testFile1   V.mapM_ assertRow d   where   assertRow r = v3 @=? (v1 + v2)   where v1 = readBS $ r ! "Open"   v2 = readBS $ r ! "High"   v3 = readBS $ r ! "Low"   v4 = readBS $ r ! "Close"      csvSettings :: CSVSettings  csvSettings = defCSVSettings { csvQuoteChar = Just '`'}    testFile1 :: FilePath  testFile1 = "C:\\Users\\ivan\\Downloads\\0005.HK.csv"      readBS :: B.ByteString -> Int  readBS = read . B.unpack

testhaskell.hs:52:5: Not in scope: `testCase'

testhaskell.hs:58:9: Illegal type signature: `V.Vector (MapRow B.ByteString)' Perhaps you intended to use -XScopedTypeVariables In a pattern type-signature

Answer

I'd strongly recommend you not do this. There are a number of high-quality CSV libraries on Hackage, and rolling your own is a recipe of problems. At FP Complete, we use csv-conduit, though cassava is also a great library. I'd recommend you try out one of them.

No comments:

Post a Comment