Haskell Text.CSV 模块
Posted
技术标签:
【中文标题】Haskell Text.CSV 模块【英文标题】:Haskell Text.CSV module 【发布时间】:2018-03-21 12:10:16 【问题描述】:为什么我会为 parseCSV
函数输入 Either Text.Parsec.Error.ParseError CSV,尽管在文档中说输出是 Either ParseError CSV?我想将 CSV 文件导入 Haskell,然后从中导出特定列,然后计算该列的统计信息。
我导入一个 CSV 文件,例如:
data = parseCSV "/home/user/Haskell/data/data.csv"
noEmpRows = either (const []) (filter (\row -> 2 <= length row))
readIndex :: Read cell => Either a CSV -> Int -> [cell]
readIndex csv index = map (read . (!!index)) (noEmpRows csv)
然后当我想readIndex data 9 :: [Integer]
时出现错误。
我还尝试了一个函数parseCSVFromFile
。
https://hackage.haskell.org/package/csv-0.1.2/docs/Text-CSV.html#t:CSV
提前感谢您的帮助。
【问题讨论】:
ParseError
只是Text.Parsec.Error.ParseError
的简称。但我想你的问题是关于错误的?它说什么?
无法将预期类型“Either a0 CSV”与实际类型“String -> Either Text.Parsec.Error.ParseError CSV”匹配
parseCSV
的类型是FilePath -> String -> Either ParseError CSV
,所以data
的类型(它不是一个有效的标识符,所以这段代码不可能编译)是String -> Either ParseError CSV
,而readIndex
的第一个参数应该是 Either a CSV
类型。
我是 Haskell 的新手,那么最终的解决方案是什么?我应该使用函数 parseCSVFromFile 还是如何重写现有函数? tnx
【参考方案1】:
您真正要问的问题是 我如何使用 Text.CSV?
给定文件 test.csv:
1,Banana,17
2,Apple,14
3,Pear,21
GHCi 中的这一行:
Prelude> Text.CSV.parseCSVFromFile "test.csv"
Right [["1","Banana","17"],["2","Apple","14"],["3","Pear","21"],[""]]
如果你想提取一列,然后为它构建一个函数:
main :: IO ()
main = do
test_csv <- parseCSVFromFile "test.csv"
case test_csv of
Right csv -> print (extractColumn csv 2 :: [Int])
Left err -> print err
extractColumn :: Read t => CSV -> Int -> [t]
extractColumn csv n =
[ read (record !! n) | record <- csv
, length record > n
, record /= [""] ]
这应该会产生输出[17,14,21]
。
因为这里有足够的失败空间(一行可能包含比n
更少的字段,或者给定行上字段n
中的字符串可能无法读取为类型t) ,如果发生错误,您可能需要处理或报告。如果上面的代码包含的字段太少,则会丢弃该行,如果该字段不是Int,则抛出Prelude.read: no parse
。考虑readEither
或readMaybe
。
【讨论】:
我将重命名两个csv
变量之一,以避免可能混淆人类读者的阴影。
感谢您的帮助,我只有一个问题,如何将输出 (IO) 从 main 保存到假设为 Integer,然后在该列表上应用 sum 函数?
@zoff 不太确定,但听起来您需要更多地了解 IO monad。尝试在这里阅读:book.realworldhaskell.org/read/io.html
@zoff:我已经将extractColumn
与 IO 层分开了。您可以类似地扩展此功能,例如sum (extractColumn ...)
或任何其他假设纯整数列表输入的计算。
@SimonShine 为什么我会收到错误消息(无法匹配类型 'Either Text.Parsec.Error.ParseError CSV' 和 '[Record]' 预期类型:CSV 实际类型:Either Text.Parsec .Error.ParseError CSV ) 当我运行命令时 extractColumn csv' 2 :: [Integer] (我已经保存了 csv'
以上是关于Haskell Text.CSV 模块的主要内容,如果未能解决你的问题,请参考以下文章