在Haskell中使用Cassava解析文件时创建列表

时间:2015-02-02 20:44:22

标签: csv haskell

我可以使用Data.Csv中的以下代码解析我的csv文件:

valuesToList :: Foo -> (Int, Int)
valuesToList (Foo a b) = (a,b)

loadMyData :: IO ()
loadMyData = do
  csvData <- BL.readFile "mydata.csv"
  case decodeByName csvData of
        Left err -> putStrLn err 
        Right (_, v) -> print $ V.toList $ V.map valuesToList v

当我运行时,我在屏幕上得到正确的输出。我遇到的问题是我不清楚如何创建一个纯函数,所以我可以使用列表的内容,如:

let l = loadMyData

其中l是类型[Int,Int]我猜它是因为我在IO Monad而且我正在做一些无可救药的傻事......

1 个答案:

答案 0 :(得分:3)

  

我正在做一些无可救药的傻事......

是的,但不要担心!

loadMyData = BL.readFile "mydata.csv"

processMyData :: String -> String
processMyData csvData = 
  case decodeByName csvData of
        Left err -> err 
        Right (_, v) -> show $ V.toList $ V.map valuesToList v

main = do
    csv <- loadMyData
    let output = processMyData csv
    print output

这样你就可以将纯粹的“let”部分与不纯的装载部分分开。这不是代码审查(如果你在那里问过,我可能会详细说明),但我会将处理输入为String -> Either String [Int, Int]或其他东西,并将失败信息保存在类型系统中。

processMyData csvData = 
  case decodeByName csvData of
        Left err -> Left err 
        Right (_, v) -> Right $ V.toList $ V.map valuesToList v

而这反过来可能只是(原谅我,如果我在某个地方犯了错误,我做它):

processMyData = fmap (V.toList . V.map valuesToList) . decodeByName

这应该有效,因为构造了how the Functor instance for Either


哦,并且还使用Control.Applicative奖励样式点:

main = do
    output <- processMyData <$> loadMyData
    print output

(如果您不理解该示例,(<$>)是中缀fmap,但这并非严格必要;因此奖励