So I was writing a small toybox of utility functions for CSV files and throughout testing the functions I'd been binding the file by hand with
table' <- parseCSVFromFile filepath
but (from Text.CSV
)
parseCSVFromFile :: FilePath -> IO (Either parsec-3.1.9:Text.Parsec.Error.ParseError CSV)
and so I had to write a quick line to strip off this either error csv crap
stripBare csv = head $ rights $ flip (:) [] csv
and redefine it as table = stripBare table'
. After this, list functions work on the csv files contents and life goes on
(Digression: Surprisingly there isn't a direct Either a b -> b
function in Data.Either
. So I used Data.Either.rights :: [Either a b] -> [b]
)
I wanted to do the work of undressing the csv type and binding it to a handle in one shot. Something like
table = stripBare $ table' <- parseCSVFromFile filepath
but this gives a parse error on (<-
) saying I may be missing a do
... then
table = stripBare $ do table' <- parseCSVFromFile filepath
yells at me saying that the last statement in a do
block must be an expression.
What am I doing wrong?
As a separate curiosity, I saw here that
do notation in Haskell desugars in a pretty simple way.
do
x <- foo
e1
e2
...
turns into
foo >>= \x ->
do
e1
e2
I find this attractive and tried the following line which gave me a type error
*Toy> :type (parseCSVFromFile "~/.csv") >>= \x -> x
<interactive>:1:52: error:
* Couldn't match type `Either
parsec-3.1.9:Text.Parsec.Error.ParseError'
with `IO'
Expected type: IO CSV
Actual type: Either parsec-3.1.9:Text.Parsec.Error.ParseError CSV
* In the expression: x
In the second argument of `(>>=)', namely `\ x -> x'
In the expression:
(parseCSVFromFile "~/.csv") >>= \ x -> x