有没有办法在Haskell中创建具有未确定数量的字段的数据类型

时间:2011-11-18 19:41:05

标签: haskell types csv

我正在尝试读取CSV文件,其中第一行包含每列的名称。然后我必须适当地编辑这些文件。我有一个想法,当我第一次读入文件,然后创建一个名为Record的新数据类型,然后所有后来的记录只是这种类型的实例,现在很明显,如果程序只需处理一种类型的CSV文件一定数量的列这很容易,但遗憾的是,情况并非总是如此。

所以我的问题是你可以做点什么吗

createRecordClass (x:xs) = data Record {addRecord(x:xs)}
addRecord (x:xs) = x::String, addRecord xs

或者我只是说疯了,只是有一个列表代表一切会更容易吗?

2 个答案:

答案 0 :(得分:1)

您可以使用Template Haskell来达到您想要的效果。这是一种通过Haskell生成Haskell代码的强大技术(类似于lisp中的宏)。

由于您提到您希望csv文件的标头创建自定义数据类型,因此您需要读入该文件,然后在Template Haskell中生成数据类型。 我看到的最接近你描述的解决方案是Yesod中的CRUD系统。查看Persistent上的Hackage个包。

答案 1 :(得分:0)

如果你在编译时有一组有限的csv文件类型,你可以用模板haskell写一些东西。例如,如果您有两种类型的csv文件:一个日志记录csv文件和一个选项csv文件,并且您有以下两个示例文件:

//sample_logger.csv
Date,Action,Succeeded
20110808,print log,true
20110929,save db,false

// sample_options.csv
Option,Value
backgroundColor,green
name,Fred

然后你可以编写一个模板haskell函数来读取这些文件的第一行,并创建一个OptionsCSVLineLoggerCSVLine数据类型,具有readOptionsCVS :: FilePath -> IO [OptionsCSVLine]readLoggerCSV :: FilePath -> IO [LoggerCSVLine]函数。例如:

-- CSVReader.hs
makeCSVReader :: String -> FilePath -> Q [Dec]
makeCSVReader dataTypeName sampleFilePath = sequence [makeDataType,makeReaderFunc] where
  makeDataType = undefined -- todo
  makeReaderFunc = undefined -- todo


-- main.hs
import CSVReader
makeCVSReader "OptionsCSV" "sample_options.csv"
makeCVSReader "LoggerCSV" "sample_logger.csv"

main = do
 logLines <- readLoggerCSV "some_logger_file.csv"
 print $ map loggerLineDate logLines -- print all the dates in the log file

但是,如果要处理运行时提供的任何csv文件,则无法以任何方式处理。