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