Home > Back-end >  Parsing custom fields with Cassava and Attoparsec
Parsing custom fields with Cassava and Attoparsec

Time:11-06

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 = ???

CodePudding user response:

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
  • Related