
I have some JSON which looks like this: {"count":2, "result":[{"LastTrade":"31.24", "Symbol":"FOO"}, {"LastTrade":"345.12", "Symbol":"BAR"}]} (named testQuoteResult below) When I try to parse this into types defined below it failed because the Double is encoded as a String. If I change the type of LastTrade in my code to String everything is ok but I am left read'ing the String. I have defined the following using Language.JsonGrammar: import Data.Iso import Language.JsonGrammar import Prelude hiding (id, (.), head, either) import Control.Category ((.)) import qualified Data.Aeson as JS import qualified Data.ByteString.Char8 as BS import qualified Data.Attoparsec as P data MyQuote = MyQuote { price :: Double, symbol :: String } deriving(Show) myQuote = $(deriveIsos ''MyQuote) instance Json MyQuote where grammar = myQuote . object ( prop "LastTrade" . prop "Symbol" ) data MyQuoteResult = MyQuoteResult { count :: Int, result :: [MyQuote] } deriving(Show) myQuoteResult = $(deriveIsos ''MyQuoteResult) instance Json MyQuoteResult where grammar = myQuoteResult . object ( prop "count" . prop "result" ) tryJSON input = case P.parse JS.json (BS.pack input) of P.Done s v -> Right v other -> Left ("failed parse " ++ show other) Using it like this:
let Right qr = tryJSON testQuoteResult fromJson qr :: Maybe MyQuoteResult Nothing
Is there some way to convince the JSON text parser to turn "12.34" into (Double 12.34)?? An example using pure aeson would be fine if required. I just decided to play with JsonGrammar since it was announced today and it sounded interesting.