Open
Description
I've got some code using a variant of the code from dependent-sum-aeson-orphans, but with ToJSON1
and FromJSON1
in the mix:
instance (ToJSON1 f, ForallF ToJSON k, Has ToJSON k) => ToJSON (DSum k f) where
toJSON ((k :: k a) :=> (f :: f a))
= whichever @ToJSON @k @a $ has @ToJSON k $
let x = toJSON k
y = toJSON1 f
in toJSON (x, y)
instance (ToJSON1 f, ForallF ToJSON k, Has ToJSON k) => ToJSON (DMap k f) where
toJSON = toJSON . DMap.toList
instance (FromJSON1 f, FromJSON (Some k), Has FromJSON k) => FromJSON (DSum k f) where
parseJSON x = do
(jk, jf) <- parseJSON x
Some.This (k :: k a) <- parseJSON jk
f <- has @FromJSON k $ parseJSON1 jf
return $ k :=> f
instance (FromJSON1 f, FromJSON (Some k), GCompare k, Has FromJSON k) => FromJSON (DMap k f) where
parseJSON = fmap DMap.fromList . parseJSON
That lets me write things like:
newtype Foo f = Foo { unFoo :: DMap FooKey f }
deriving (Eq, Ord, Show, Generic)
instance ToJSON1 f => ToJSON (Foo f)
instance FromJSON1 f => FromJSON (Foo f)
which is quite a bit nicer than having to list out (ToJSON (f Int), ToJSON (f Bool), ...) =>
for all of the types associated with the constructors of FooKey
.
I have used this in anger much, so I'm not sure what the various pros and cons are. If there is interest in this I can put it into a PR which adds the above code in a separate module.
Metadata
Assignees
Labels
No labels