4

I am trying to read CSV file which I succeded with some examples. Here is what I've got

*Main System.IO> let result=parseCSV contents
*Main System.IO> result
Right [["Name","Value","Amount"],["Rob","1","10"],["Bob","1.42","15.3"],["Tom","452.2","23.1"]]

But If I try to read value from this array I get an error

*Main System.IO> head result

<interactive>:21:6:
    Couldn't match expected type `[a0]'
            with actual type `Either ParseError [[String]]'
In the first argument of `head', namely `result'
In the expression: head result
In an equation for `it': it = head result

So how can I get Rid of the Right and actually use the list ?

*Main System.IO> :t result
result :: Either ParseError [[String]]
Tom
  • 93
  • 1
  • 4

3 Answers3

3

To get rid of the Right, you need to decide what to do when you get an error instead. If you just want to get an empty result you could use:

justTheResult :: [[[Char]]]
justTheResult = either (const []) id result

If you want an error to be raised, you could use:

justTheResult :: [[[Char]]]
justTheResult = either (const $ error "Couldn't parse CSV") id result

If you want to keep the error for later, but do something with the result, you could instead use Either's Functor (Either e) instance:

errorOrNumberOfRows :: Either ParseError Int
errorOrNumberOfRows = fmap length result

Now you'll be in the same place accessing that Int length

Cirdec
  • 24,019
  • 2
  • 50
  • 100
1

Change it to

*Main System.IO> let (Right result) = parseCSV contents
*Main System.IO> head result
Rob Stewart
  • 1,812
  • 1
  • 12
  • 25
1

If you really want to ignore the error, the following shoud do the job:

either (const []) id (parseCSV contents)

It will give you an empty list in case of parse errors.

Ingo
  • 36,037
  • 5
  • 53
  • 100