问题
I've been fighting with a simple ADT, trying to get it to round-trip back and forth to JSON, but I've had no luck, no matter how I try to massage or modify the type. What am I missing?
When it compiles, I always get the same runtime error:
> let t = Fahrenheit
> fromJSON $ toJSON t
Error "when expecting a (), encountered Object instead"
Trying this just gives me "Nothing", presumably because of the same error: decode $ encode t
I've tried to follow these sources, but I can't seem to get around this runtime error, no matter what I try: Haskell :: Aeson :: parse ADT based on field value https://www.fpcomplete.com/user/Geraldus/algebraic-data-types-adts-with-aeson
Here's one form of the code I'm using. At first, I tried to use this as a type embedded in another type, but when that didn't work I added the "value" key to try to make parsing of this easier (no luck).
data TemperatureType = Celsius
| Fahrenheit
deriving (Show,Read,Typeable,Data,Eq)
-- This doesn't work either
-- $(deriveJSON defaultOptions ''TemperatureType)
instance ToJSON TemperatureType where
toJSON Fahrenheit = object [ "value" .= String "Fahrenheit" ]
toJSON Celsius = object [ "value" .= String "Celsius" ]
instance FromJSON TemperatureType where
parseJSON (Object x) = toTemperatureType <$> x .: "value"
toTemperatureType :: Text -> TemperatureType
toTemperatureType "Fahrenheit" = Fahrenheit
toTemperatureType "Celsius" = Celsius
回答1:
Haskell need help from you about the type of your expression result since in the current call it's not possible to infer it:
> fromJSON $ toJSON t :: Result TemperatureType
来源:https://stackoverflow.com/questions/28143342/haskell-adts-with-aeson