5

有人建议我将csv-conduit作为一个很好的 Haskell 包来处理 CSV 文件。我想了解它是如何工作的,但是对于新手 Haskell 程序员来说,文档太简洁了。

有没有办法让我通过 GHCi 中的反复试验来弄清楚它是如何工作的?

更具体地说,我应该GHCi 加载模块和文件,还是应该编写一个简单的 HS 文件来加载它们,然后以交互方式移动?


我提到了 csv-conduit,但我愿意使用任何CSV 包。我只需要拿到一个并玩弄它,直到我感到自在(就像我在 IDLE 中所做的那样)。

4

3 回答 3

5

看看下面的函数:readCSVFile :: :: (MonadResource m, CSV ByteString a) => CSVSettings -> FilePath -> m [a]

调用起来相对简单,因为我们只需要一个CSVSettings,例如defCSVSettings,和一个FilePath(aka String),"file.csv"或其他东西。

因此,在调用之后,我们得到(MonadResource m, CSV ByteString a). 我们可以一次解决这个问题,以找出合适的类型。我们正在执行IO这个操作,所以 for MonadResource mm应该只是ResourceT IO,它恰好是MonadBaseControl IOas 要求的一个实例runResourceT。这是一个conduit具体的事情。

对于CSV ByteString a,我们需要找到 的哪些实例CSV。为此,请访问http://hackage.haskell.org/packages/archive/csv-conduit/0.2.1.1/doc/html/Data-CSV-Conduit.html#t:CSV(其中包的文档在我看来有点令人讨厌的是所有都塞进了类型类...)然后单击 Instances 以查看我们有哪些可用的实例CSV ByteString a。两个选项是CSV ByteString ByteStringCSV ByteString Text

在这两者中,Text更可取,因为它处理 unicode,而 CSV 不太可能包含二进制数据。ByteString或多或少类似于一段[Word8]时间Text更类似于[Char]这可能是您想要的。因此,a应该是Text(尽管ByteString仍然有效)。

这意味着函数调用的结果是ResourceT IO [Row Text]. 我们对此无能为力,但因为ResourceT它是一个 monad 转换器,我们可以使用 函数轻松“弹出” monad 转换层runResourceT。因此,

readFile :: FilePath -> IO [Row Text]
readFile = runResourceT . readCSVFile defCSVSettings

这很容易在 main 中使用,然后您可以使用 a或 a[Row Text]进行迭代以获取各个行。mapfold

要在 GHCI 中运行这类事情,您绝对必须特别指出类型。原因是结果类实例不依赖于任何参数;因此,对于任何一组CSVSettingsand FilePathreadCSVFile只要它们 asmMonadResource ma的一个实例,就可以返回任意数量的不同类型CSV ByteString a。因此,我们必须明确指出 GHCi 您想要哪种类型。

于 2012-07-19T00:04:21.037 回答
2

你试过Text.CSV吗?如果您刚开始使用 Haskell,它可能更合适,因为它更简单。至于探索新的模块,你可以把它加载到 GHCi 中,不需要编写额外的文件。

于 2012-07-18T20:08:20.230 回答
0

这适用于最新版本的 csv-conduit 包(版本 0.6.3)。请注意 readCsv 的签名,没有它我无法编译。

{-# LANGUAGE OverloadedStrings #-}

import Data.CSV.Conduit
import Data.Text (Text)
import qualified Data.Vector as V
import qualified Data.ByteString as B

csvset :: Char ->  CSVSettings 
csvset c =  CSVSettings {csvSep  = c, csvQuoteChar = Just '"'}

readCsv :: String -> Char -> IO (V.Vector (Row Text))
readCsv fp del = readCSVFile (csvset del) fp

main = readCsv "C:\\mydir\\myfile.csv" ';'
于 2014-11-26T00:46:57.967 回答