如何使用parsec解析yahoo csv

时间:2014-04-22 06:09:12

标签: haskell

如何解析数组,如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

更新

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:不在范围内:`testCase'

testhaskell.hs:58:9:     非法类型签名:`V.Vector(MapRow B.ByteString)'       也许您打算使用-XScopedTypeVariables     在模式类型签名

1 个答案:

答案 0 :(得分:5)

我强烈建议您这样做。 Hackage上有许多高质量的CSV库,而自己滚动就是一个问题。在FP Complete,我们使用csv-conduit,尽管cassava也是一个很棒的库。我建议你尝试其中一个。