2017-02-13 14 views
1

カスタムデータ型でcsv-conduitを使用する方法についてはかなり混乱しています。私は、このいずれかのように株価データの行を取るしたいと思います:CSVファイルをcsv-conduitでカスタムデータ型にパースする

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

と、私は以下の私のMWEに宣言したStockInfo型にそれを解析します。 StockInfoのインスタンスをFromNamedRecordToNamedRecord、およびCSV ByteStringにするために必要なドキュメントから収集しました。私は最初の2日間はそうしたと信じていますが、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延ByteString))=> CSV 'インスタンスを定義しますs(Named a) ' - ' Named'は単なるアイデンティティーであり、 '{To/From} NamedRecord'インスタンスを持っていますので、このインスタンスを自分で書く必要はありません。本当に必要なら、 '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 
       ] 
関連する問題