Date un'occhiata al seguente funzione: readCSVFile :: :: (MonadResource m, CSV ByteString a) => CSVSettings -> FilePath -> m [a]
sua relativamente semplice da chiamare, come abbiamo solo bisogno di un CSVSettings
, come defCSVSettings
, e un FilePath
(aka String
), "file.csv"
o qualcosa del genere.
Così, dopo la chiamata, otteniamo (MonadResource m, CSV ByteString a)
. Possiamo risolvere questo alla volta per capire un tipo appropriato per questo. Stiamo eseguendo IO
in questa operazione, quindi per MonadResource m
, m
dovrebbe essere solo ResourceT IO
, che risulta essere un'istanza di MonadBaseControl IO
come richiesto da runResourceT
. Questa è una cosa specifica di conduit
.
Per il CSV ByteString a
, dobbiamo trovare quali istanze di CSV
. Per fare ciò, andare a http://hackage.haskell.org/packages/archive/csv-conduit/0.2.1.1/doc/html/Data-CSV-Conduit.html#t:CSV (dove la documentazione per il pacchetto è a mio parere in qualche modo odiosamente inserita nella classe di caratteri ...) e fare clic su Istanze per vedere quali istanze disponibili abbiamo del modulo CSV ByteString a
. Le due opzioni sono CSV ByteString ByteString
e CSV ByteString Text
.
Di questi due, Text
è preferibile perché gestisce unicode e CSV non conterrà probabilmente dati binari. ByteString
è più o meno simile a [Word8]
mentre Text
è più simile a [Char]
che è probabilmente quello che vuoi. Quindi, a
dovrebbe essere Text
(anche se ByteString
funzionerà ancora).
Ciò significa che il risultato della chiamata di funzione è ResourceT IO [Row Text]
. Non possiamo fare molto con questo, ma poiché ResourceT
è un trasformatore monad, possiamo facilmente "far scattare" il layer di trasformazione monad con la funzione runResourceT
. Così,
readFile :: FilePath -> IO [Row Text]
readFile = runResourceT . readCSVFile defCSVSettings
che è facilmente utilizzabile all'interno, diciamo, principale per arrivare al [Row Text]
che è quindi possibile iterare su con un map
o un fold
per mettere le mani sulle singole righe.
Per eseguire questo genere di cose in GHCI è assolutamente necessario indicare il tipo. Il motivo è che l'istanza della classe result non dipende da nessuno dei parametri; pertanto, per qualsiasi serie di CSVSettings
e FilePath
, readCSVFile
, è possibile restituire un numero qualsiasi di tipi diversi purché comesia un'istanza di MonadResource m
e a
sia un'istanza di CSV ByteString a
. Pertanto, dobbiamo indicare esplicitamente a GHCi quale tipo desideri.
con il pacchetto csv-condotto-0.6.6 firma readCsv dovrebbe essere 'readCsv :: String -> Char -> IO (V.Vector (Row B.ByteString))', sostituendo il testo con Fila Row B. ByteString – Janthelme