I have some JSON fields stored in a database which contain a String -> Double mapping, e.g.:
{
"some type of thing": 0.45,
"other type of thing": 0.35,
"something else": 0.2
}
I want to represent this as a ThingComposition
:
data ThingType = ThingTypeSome
| ThingTypeOther
| ThingTypeUnknown Text
-- | Create a ThingType from a text representation
txtToThing :: Text -> ThingType
txtToThing "some type of thing" = ThingTypeSome
txtToThing "other type of thing" = ThingTypeOther
txtToThing s = ThingTypeUnknown s
-- Deserialise ThingType from JSON text
instance FromJSON ThingType where
parseJSON val = withText "ThingType" (return . txtToThing) val
data ThingComposition = ThingComposition [(ThingType, Double)]
| InvalidThingComposition
instance FromJSON ThingComposition where
parseJSON val = withObject "ThingComposition"
_
val
The _
is what I have no idea how to fill out. I've tried something like the following but I can't get the types to align and I can't work out the best way to do this, given that it's possible that the JSON representation won't match the types, but I don't want to create a list of [(Either String ThingType, Either String Double)]
. How can I parse that the object at the top into the ThingComposition
type?
_ = (return . ThingComposition) . map (bimap parseJSON parseJSON) . toList
CodePudding user response:
I would make some supporting instances for your ThingType
, then reuse the FromJSON (HashMap k v)
instance.
-- added "deriving Eq" to your declaration; otherwise unchanged
data ThingType = ThingTypeSome
| ThingTypeOther
| ThingTypeUnknown Text
deriving Eq
thingToTxt :: ThingType -> Text
thingToTxt ThingTypeSome = "some type of thing"
thingToTxt ThingTypeOther = "other type of thing"
thingToTxt (ThingTypeUnknown s) = s
instance FromJSONKey ThingType where
fromJSONKey = FromJSONKeyText txtToThing
instance Hashable ThingType where
hashWithSalt n = hashWithSalt n . thingToTxt
With that supporting code, you now have a FromJSON
instance for HashMap ThingType Double
, which is superior in many ways to a [(ThingType, Double)]
.