2017-02-13 8 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 

내가 아래에있는 내 MWE에서 선언 한 StockInfo 형으로 그것을 구문 분석합니다. 나는 내 StockInfo 인스턴스를 FromNamedRecord, ToNamedRecordCSV 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을 A, ToNamedRecord A, CSV의 (인 mapRow ByteString)) => CSV s (Named 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 
       ]