简体   繁体   中英

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:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM