The code below generates orphan instances for store
. It works fine for aeson 1.4.7.1
but generates error in aeson 2.0.3.0
.
{-# LANGUAGE DeriveDataTypeable,DeriveGeneric,TemplateHaskell,GeneralizedNewtypeDeriving, OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
import Data.Store (Store)
import TH.Derive
import Data.Scientific
import Data.Aeson (Value)
-- This will allow us to serialize Aeson objects
$($(derive [d| instance Deriving (Store (Scientific)) |]))
$($(derive [d| instance Deriving (Store (Value)) |])) -- Template haskell derivation of Store instance for Value
With aeson 2.0.3.0
(as listed in stackage LTS-20.13
- working code was compiled using LTS-16.31
with store 0.7.1
and aeson 1.4.7.1
), it now throws errors about some store instance missing for aeson internal object - top level error below:
No instance for (Store
aeson-2.0.3.0:Data.Aeson.Types.Internal.Object)
arising from a use of ‘store-0.7.16:Data.Store.Impl.size’
Will appreciate pointers on how to fix this.
Added the following template haskell derivations (along with ScopedTypeVariable
pragma to compile) following suggestions of @daniel-wagner:
$($(derive [d| instance Deriving (Store (Key)) |]))
$($(derive [d|
instance Store a => Deriving (Store (KeyMap a))
|]))
Looks like Object
(which isn't actually an internal-only data structure; it's also exported from Data.Aeson.Types
with no .Internal
) has changed from being a type alias for HashMap
(which has a Store
instance) to being an abstract data structure (that does not have an instance). You'll need to write Store
instances for the Key
and KeyMap
types, then you can be on your way. You might, for example, use toList
and fromList
for a programmer-cheap implementation for KeyMap
:
instance Store v => Store (KeyMap v) where
size = contramap toList size
poke = contramap toList poke
peek = fmap fromList peek
And similarly toText
and fromText
for Key
:
instance Store Key where
size = contramap toText size
poke = contramap toText poke
peek = fmap fromText peek
If you are writing a library, you might want to shove these instances into their own package that is somehow easily discoverable on Hackage -- say, by naming it store-aeson
or something -- to reduce the pain of orphan instances. If you're just writing an application, you're probably fine. (I dream of there one day being a searchable orphan instance registry... one of these days, in my copious free time...)