I'm able to parse my csv file using the following code from Data.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...
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. 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.
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.
Oh, and also use Control.Applicative
for bonus style points:
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 )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.