2017-02-13 84 views
1

對於如何將csv-conduit與自定義數據類型一起使用,我感到非常困惑。我想利用股票數據的一排像這樣:使用csv-conduit將CSV文件解析爲自定義數據類型

Date,Open,High,Low,Close,Volume,Adj Close 
2017-02-10,2312.27002,2319.22998,2311.100098,2316.100098,3475020000,2316.100098 

,並解析到StockInfo類型我在下面MWE聲明。我從文檔中收集了我需要使我的StockInfoFromNamedRecordToNamedRecordCSV ByteString的實例。我相信我已經爲前兩項這樣做了,但我不明白如何實施CSV ByteString的必要方法。任何幫助將不勝感激。

MWE:

{-# LANGUAGE MultiParamTypeClasses #-} 
{-# LANGUAGE OverloadedStrings  #-} 

module Lib 
    (readStocks 
    ) where 

import   Data.ByteString 
import   Data.Conduit 
import   Data.Conduit.Binary 
import   Data.Conduit.List   as CL 
import   Data.CSV.Conduit 
import   Data.CSV.Conduit.Conversion 
import   Data.Text     (Text) 
import   Data.Vector 
import   System.IO 

readStocks :: FilePath -> IO (Vector StockInfo) 
readStocks fp = readCSVFile defCSVSettings fp 

data StockInfo = StockInfo 
    { date  :: !String 
    , open  :: !Double 
    , high  :: !Double 
    , low  :: !Double 
    , close :: !Double 
    , volume :: !Integer 
    , adjClose :: !Double 
    } 

instance FromNamedRecord StockInfo where 
    parseNamedRecord m = 
    StockInfo <$> 
    m .: "Date" <*> 
    m .: "Open" <*> 
    m .: "High" <*> 
    m .: "Low" <*> 
    m .: "Close" <*> 
    m .: "Volume" <*> 
    m .: "Adj Close" 

instance ToNamedRecord StockInfo where 
    toNamedRecord (StockInfo date open high low close volume adjClose) = 
    namedRecord [ "Date" .= date 
       , "Open" .= open 
       , "High" .= high 
       , "Low" .= low 
       , "Close" .= close 
       , "Volume" .= volume 
       , "Adj Close" .= adjClose 
       ] 

instance CSV ByteString StockInfo where 
    -- rowToStr = undefined 
    -- intoCSV = undefined 
    -- fromCSV = undefined 
+1

庫中已定義了一個實例'(FromNamedRecord一,ToNamedRecord一個,CSV S(MapRow字節字符串))=> CSV s(命名爲a)'--' Named'就是身份,而且你有'{To/From} NamedRecord'實例,所以你不需要自己寫這個實例 - 只需使用'Named'實例。如果你真的想要,你可以根據庫提供的通用定義你的'CSV ByteString StockInfo'實例。 – user2407038

+0

明白!我認爲這沒有意義,但這是我的最好理解。 – anthonybrice

回答

2

這是我應該做的:

{-# LANGUAGE OverloadedStrings  #-} 

module Lib 
    (readStocks 
    ) where 

import   Data.ByteString 
import   Data.Conduit 
import   Data.Conduit.Binary 
import   Data.CSV.Conduit 
import   Data.CSV.Conduit.Conversion 
import   Data.Text     (Text) 
import   Data.Vector 
import   System.IO 

readStocks :: FilePath -> IO (Vector (Named StockInfo)) 
readStocks fp = readCSVFile defCSVSettings fp 

data StockInfo = StockInfo 
    { date  :: !String 
    , open  :: !Double 
    , high  :: !Double 
    , low  :: !Double 
    , close :: !Double 
    , volume :: !Integer 
    , adjClose :: !Double 
    } deriving (Show, Eq, Read) 

instance FromNamedRecord StockInfo where 
    parseNamedRecord m = 
    StockInfo <$> 
    m .: "Date" <*> 
    m .: "Open" <*> 
    m .: "High" <*> 
    m .: "Low" <*> 
    m .: "Close" <*> 
    m .: "Volume" <*> 
    m .: "Adj Close" 

instance ToNamedRecord StockInfo where 
    toNamedRecord (StockInfo date open high low close volume adjClose) = 
    namedRecord [ "Date" .= date 
       , "Open" .= open 
       , "High" .= high 
       , "Low" .= low 
       , "Close" .= close 
       , "Volume" .= volume 
       , "Adj Close" .= adjClose 
       ]