2

I have a CSV with fields in it which contain unit values which I have to parse out. As a simple example:

data EValue = Farads Double | MicroFarads Double | PicoFarads Double

Thus I need to parse something like the following:

parseEValue = farads <|> micro <|> pico
  where farads = Farads <$> double <* string "F"
        micro  = MicroFarads <$> double <* string "µF"
        pico   = PicoFarads <$> double <* string "pF"

How do I include this in an instance definition for FromField for Cassava?

instance FromField EValue where
  parseField = ???
GTF
  • 8,031
  • 5
  • 36
  • 59

1 Answers1

3

You just need to run attoparsec on the Field you get and then put the result in the Parser monad, like this: parseField = either fail pure . parseOnly parseEValue.

For completeness, here's full working code:

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative
import Data.Attoparsec.ByteString.Char8
import Data.Csv

data EValue = Farads Double | MicroFarads Double | PicoFarads Double

parseEValue = farads <|> micro <|> pico
  where farads = Farads <$> double <* string "F"
        micro  = MicroFarads <$> double <* string "µF"
        pico   = PicoFarads <$> double <* string "pF"

instance FromField EValue where
  parseField = either fail pure . parseOnly parseEValue