如何使用Haskell的Data.Csv将无表头CSV读取为自定义数据类型?
问题:将无表头CSV解码为自定义Haskell数据类型
我有一个路径为filePath的无表头CSV文件,包含两列数据,示例如下:
john,304 sarah,300 ...
目前我已能通过以下代码将其读取为(String, Integer)类型的列表:
import Data.Csv as Csv import Data.ByteString.Lazy as BL import Data.Vector as V ... results <- fmap V.toList . Csv.decode @(String,Integer) Csv.NoHeader <$> BL.readFile filePath -- Right [("john",300),("sarah",302)]
现在我定义了如下自定义数据类型:
data PersonnelData = PersonnelData { name :: !String , amount :: !Integer } deriving (Show, Generic, Csv.FromRecord)
请问如何修改上述代码,将CSV文件解码/读取为该自定义数据类型?
解决方案
只需要把解码时指定的类型从(String, Integer)替换为自定义类型PersonnelData即可。由于你已经通过Generic和Csv.FromRecord派生了必要的实例,cassava库会自动按照字段顺序匹配无表头CSV的列(CSV列顺序需与数据类型的字段顺序一致)。
修改后的代码如下:
import Data.Csv as Csv import Data.ByteString.Lazy as BL import Data.Vector as V ... results <- fmap V.toList . Csv.decode @PersonnelData Csv.NoHeader <$> BL.readFile filePath -- Right [PersonnelData {name = "john", amount = 300}, PersonnelData {name = "sarah", amount = 302}]
关键点说明
- 确保
PersonnelData的字段顺序和CSV的列顺序完全对应(本例中CSV第一列对应name,第二列对应amount,顺序匹配) - 派生的
Generic和Csv.FromRecord实例是cassava自动完成解析的核心,无需手动编写解析逻辑
内容的提问来源于stack exchange,提问作者Hud
相关产品推荐
相关产品推荐

