如何为多态类型手工编写aeson实例,如:
data Show a => Translatable a = Translatable (Map.Map String a)
deriving (Show, Eq, Typeable)我想编码一个
Translatable $ Map.fromList [("key", "value"), ("key2", "value2")]到像{ "key", "value", "key2", "value2" }这样的json对象
到目前为止,我尝试的是:
import qualified Data.Aeson as A
import Data.Data (Typeable)
import qualified Data.Map as Map
data Show a => Translatable a = Translatable (Map.Map String a)
deriving (Show, Eq, Typeable)
instance Show a => A.ToJSON (Translatable a) where
toEncoding xs = A.object $ map (.=) (Map.toList xs)错误
Couldn't match type ‘A.Value’
with ‘Data.Aeson.Encoding.Internal.Encoding' A.Value’
Expected type: A.Encoding
Actual type: A.Value伊索文档展示:type Encoding = Encoding' Value
但是A.Encoding‘不在范围之内
Not in scope: data constructor ‘A.Encoding'’我做错什么了?
编辑:
我把我的翻译变成了一种类型
type Translatable a = Map.Map String a现在,它可以工作,而无需将可翻译的实例添加到ToJSON中。
但最初的问题仍然是问题。
发布于 2020-04-15 22:03:30
您正在将toJSON和toEncoding函数混合起来。只需实现toJSON实例的ToJSON函数即可。我引进了不合格的Data.Aeson,以减少与运营商的斗争。
import Data.Aeson
import qualified Data.Text as T
--- etc.
instance Show a => ToJSON (Translatable a) where
toJSON (Translatable myMap) = toJSON
[ object [ T.pack key .= show val ] | (key, val) <- Map.toList myMap ]我们使用json对象列表上的toJSON函数来创建json数组。T.pack key是必需的,因为您的地图键是String的,但是.=需要Text。
https://stackoverflow.com/questions/61234262
复制相似问题