0

We are trying to decode a JSON object using the Aeson-JSON hackage using the following data:

data Car = Car
  { carPosition  :: Position,
    carColor     :: Color,
    carDirection :: Direction }
  deriving (Show, Generic)

Created an instance for Car, and did the same for the data types Postion, Direction:

instance FromJSON Position
instance FromJSON Direction
instance FromJSON Car

But now the trouble starts, the data type Color comes from the Gloss hackage and the value is e.g. written as Red. The Color data only knows: deriving Show, so no possibility of adding the deriving Generic. We tried the following code:

instance FromJSON Color where
      parseJSON (Object v) = Color <$>
        v .: "carColor"

It complains about not matching type Picture -> Picture and we expected something like Color.

Our question is: how can we use the data Color from Gloss to read a JSON object like

{ "carPostion": { "x": 0, "y": 10}, "carColor": "Red", "carDirection": "Up" }

We have tried to read a JSON object without carColor (just for testing purposes) and that works.

UPDATE: It looks like this question: Haskell Data.Decimal as Aeson type except in our case we want to use Color where in the given like Data.Decimal is the trouble maker.

Viletung
  • 137
  • 2
  • 8
  • What does `Color` looks like? Furthermore it does not make much sense for me that you parse this that way. I would explect `parseJSON` to parse a JSON string, or something equivalent. – Willem Van Onsem Oct 27 '17 at 12:33
  • @WillemVanOnsem I have updated my question. The main problem is `Color`, without this property we can successfully read a JSON object with the given code. – Viletung Oct 27 '17 at 12:50

1 Answers1

0

If all you need is to parse base strings, this is pretty simple:

instance FromJSON Color where
  parseJSON (String s) = maybe mzero return $ stringToColor s 
  parseJSON _ = mzero


stringToColor :: String -> Maybe Color
stringToColor s 
  | s == "red" = Just red
  | s == "blue" = Just blue 
  ... -- fill in all of your options from Gloss
  | otherwise = Nothing 

This allows you to turn a simple string into one of your Color objects. Once you have the FromJSON instance for Color, you can just use instance FromJSON Car.

jkeuhlen
  • 4,401
  • 23
  • 36
  • Thank you, I guess there is no direct way to do this (without converting from a string to a color). Anyway, this solves pur problem :) – Viletung Oct 28 '17 at 07:05