在 JSON 个实例中使用数据类型名称
Use datatype name in JSON instance
我正在尝试为 FromJSON
类型类编写一个通用实例。这个想法是在解析 JSON 期间使用数据类型名称。我认为这是 GHC 应该能够做到的事情,但到目前为止我的尝试都失败了。下面是使用 Typeable
类型类的最简单版本。
data GetResponse a = GetResponse { getCode :: Int, getItem :: a } deriving (Show)
instance (Typeable a, FromJSON a) => FromJSON (GetResponse a) where
parseJSON =
withObject "GetResponse" $ \o -> do
getCode <- o .: "code"
getItem <- o .: toLower (pack typeName)
return GetResponse {..}
where
typeName = showsTypeRep (typeRep Proxy :: Proxy a) ""
编译失败,出现以下错误:
[1 of 1] Compiling Main ( generics.hs, interpreted )
generics.hs:74:48: error:
• Could not deduce (Typeable a0) arising from a use of ‘typeRep’
from the context: (Typeable a, FromJSON a)
bound by the instance declaration at generics.hs:66:10-61
The type variable ‘a0’ is ambiguous
• In the first argument of ‘showsTypeRep’, namely
‘(typeRep (Proxy :: Proxy a))’
In the second argument of ‘($)’, namely
‘showsTypeRep (typeRep (Proxy :: Proxy a)) ""’
In the second argument of ‘($)’, namely
‘pack $ showsTypeRep (typeRep (Proxy :: Proxy a)) ""’
我尝试用泛型做同样的事情,但得到了同样的错误。
启用 ScopedTypeVariables
扩展我能够编译这个例子。使用此扩展,Proxy a
中的 a
对应于实例声明中的相同 a
。
我正在尝试为 FromJSON
类型类编写一个通用实例。这个想法是在解析 JSON 期间使用数据类型名称。我认为这是 GHC 应该能够做到的事情,但到目前为止我的尝试都失败了。下面是使用 Typeable
类型类的最简单版本。
data GetResponse a = GetResponse { getCode :: Int, getItem :: a } deriving (Show)
instance (Typeable a, FromJSON a) => FromJSON (GetResponse a) where
parseJSON =
withObject "GetResponse" $ \o -> do
getCode <- o .: "code"
getItem <- o .: toLower (pack typeName)
return GetResponse {..}
where
typeName = showsTypeRep (typeRep Proxy :: Proxy a) ""
编译失败,出现以下错误:
[1 of 1] Compiling Main ( generics.hs, interpreted )
generics.hs:74:48: error:
• Could not deduce (Typeable a0) arising from a use of ‘typeRep’
from the context: (Typeable a, FromJSON a)
bound by the instance declaration at generics.hs:66:10-61
The type variable ‘a0’ is ambiguous
• In the first argument of ‘showsTypeRep’, namely
‘(typeRep (Proxy :: Proxy a))’
In the second argument of ‘($)’, namely
‘showsTypeRep (typeRep (Proxy :: Proxy a)) ""’
In the second argument of ‘($)’, namely
‘pack $ showsTypeRep (typeRep (Proxy :: Proxy a)) ""’
我尝试用泛型做同样的事情,但得到了同样的错误。
启用 ScopedTypeVariables
扩展我能够编译这个例子。使用此扩展,Proxy a
中的 a
对应于实例声明中的相同 a
。