在 Haskell 中使用 Cassava 解析文件时创建列表
Creating a list when parsing a file using Cassava in 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 中并且我正在做一些无可救药的傻事...
I'm doing something hopelessly silly...
是的,但不用担心!
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
,但这不是绝对必要的;因此 bonus)
我可以使用来自 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 中并且我正在做一些无可救药的傻事...
I'm doing something hopelessly silly...
是的,但不用担心!
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
,但这不是绝对必要的;因此 bonus)