I'm trying to parse a CSV file using Cassava. I want a function that returns Nothing
if parse was unsuccessful and Just (V.Vector (String, String, String))
otherwise.
I'm using the code below:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: Maybe (V.Vector Dataset)
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v
The error is:
• Couldn't match type ‘IO’ with ‘Maybe’
Expected type: Maybe BL.ByteString
Actual type: IO BL.ByteString
• In a stmt of a 'do' block: csvData <- BL.readFile "TAEE3.SA.csv"
In the expression:
do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
In an equation for ‘someFunc’:
someFunc
= do csvData <- BL.readFile "TAEE3.SA.csv"
case decode HasHeader csvData ::
Either String (V.Vector (String, String, String))
of
Left a -> Nothing
Right v -> Just v
|
14 | csvData <- BL.readFile "TAEE3.SA.csv"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
It's like the <-
function is not working at all. Isn't it supposed to return an a
in IO a
monad?
While <-
does give you the a
in IO a
, it doesn't do it by taking it out of the IO monad. In general, it's impossible to take a value out of monads. What it actually does is put the rest of the do
block in the monad too. To account for this, you need to make your function return its result in IO
, and then add a return
to wrap your final Maybe
back in IO
:
{-# LANGUAGE ScopedTypeVariables #-}
module Lib
( someFunc
) where
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
type Dataset = (String, String, String)
someFunc :: IO (Maybe (V.Vector Dataset))
someFunc = do
csvData <- BL.readFile "TAEE3.SA.csv"
return $ case decode HasHeader csvData :: Either String (V.Vector (String, String, String)) of
Left a -> Nothing
Right v -> Just v