[英]Creating a list when parsing a file using Cassava in Haskell
I'm able to parse my csv file using the following code from Data.Csv: 我可以使用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
When I run this I get the correct output on the screen. 当我运行它时,我在屏幕上得到正确的输出。 The problem I have is I'm not clear how to create a pure function so I can consume the contents of the list, as in:
我遇到的问题是我不清楚如何创建一个纯函数,所以我可以使用列表的内容,如:
let l = loadMyData
Where l is of type [Int,Int]
I'm guessing it's because I'm in the IO Monad and I'm doing something hopelessly silly... 其中l的类型为
[Int,Int]
我猜这是因为我在IO Monad,我正在做一些无可救药的傻事......
I'm doing something hopelessly silly...
我正在做一些无可救药的傻事......
Yes, but worry not! 是的,但不要担心!
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
This way you separate the pure, "let" part from the impure loading part. 这样您就可以将纯粹的“let”部分与不纯的装载部分分开。 This isn't Code Review (if you asked there, I could probably elaborate more), but I'd type the processing as
String -> Either String [Int, Int]
or something and keep the failure information in the type system. 这不是代码审查(如果你在那里问我,我可能会详细说明),但我将处理类型为
String -> Either String [Int, Int]
或类似的东西,并将故障信息保存在类型系统中。
processMyData csvData =
case decodeByName csvData of
Left err -> Left err
Right (_, v) -> Right $ V.toList $ V.map valuesToList v
And that in turn could simply be (pardon me if I make a mistake somewhere, I'm doing it live ): 而这反过来可能只是(原谅我,如果我在某个地方犯了错误,我正在做它 ):
processMyData = fmap (V.toList . V.map valuesToList) . decodeByName
That should work because of how the Functor
instance for Either
is constructed. 这应该工作,因为如何构造
Either
的Functor
实例 。
Oh, and also use Control.Applicative
for bonus style points: 哦,还可以使用
Control.Applicative
获得奖励样式点:
main = do
output <- processMyData <$> loadMyData
print output
(in case you don't understand that example, (<$>)
is infix fmap
, but that's not stricly necessary; hence bonus ) (如果您不理解该示例,
(<$>)
是中缀fmap
,但这不是非常必要的;因此奖金 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.