No Store instance for Aeson object.

huangapple go评论58阅读模式
英文:

No Store instance for Aeson object

问题

以下是您要翻译的部分:

"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.

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.

Update
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))
|]))"

英文:

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.

Update

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))
    |]))

答案1

得分: 3

以下是翻译的代码部分:

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](https://hackage.haskell.org/package/aeson-2.1.2.1/docs/Data-Aeson-KeyMap.html#t:KeyMap) (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...)
英文:

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...)

huangapple
  • 本文由 发表于 2023年3月7日 22:13:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75663100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定