我正在尝试解析形式的嵌入式JSON
{
"foo":"bar",
"baz":"\{\"somekey\":\"someval\"\}"
}
与埃森(Eeson)在Haskell。这是我的类型:
data BaseType = BaseType { foo :: String, baz :: EmbeddedType } deriving(Show)
instance FromJSON BaseType where
parseJSON = withObject "BaseType" $ \o -> do
foo <- o .: "foo"
baz <- o .: "baz"
return $ BaseType { foo=foo, baz=baz }
data EmbeddedType = EmbeddedType { somekey :: String }
instance FromJSON EmbeddedType where
parseJSON = withObject "EmbeddedType" $ \o -> do
somekey <- o .: "somekey"
return $ EmbeddedType {somekey=somekey}
很显然,FromJSON
的{{1}}实例不起作用,因为它将其视为BaseType
而不是用于解析的更多JSON。我试图找到一种在Value String
实例中使用decodeEither
的方法,但是这要求我做一些不可思议的事情才能将FromJSON BaseType
转换为String
,我觉得必须有一种更整洁的方式,可能与ByteString
有关。
我如何才能使其正常工作?
答案 0 :(得分:2)
我想可能是这样(未经测试):
instance FromJSON BaseType where
parseJSON = withObject "BaseType" $ \o -> do
foo <- o .: "foo"
bazText <- o .: "baz"
baz <- withEmbeddedJSON "EmbeddedType" parseJSON (String bazText)
return $ BaseType { foo=foo, baz=baz }
或者您可以考虑将对withEmbeddedJSON
的调用移到EmbeddedType
实例中;那么o .: "baz"
应该可以在BaseType
实例中正常工作,但代价是不再拥有只对EmbeddedType
进行解析而不进行解串的解析器的句柄:
instance FromJSON BaseType where
parseJSON = withObject "BaseType" $ \o -> do
foo <- o .: "foo"
baz <- o .: "baz"
return $ BaseType { foo=foo, baz=baz }
instance FromJSON EmbeddedType where
parseJSON = withEmbeddedJSON "EmbeddedType" . withObject "EmbeddedType" $ \o -> do
somekey <- o .: "somekey"
return $ EmbeddedType {somekey=somekey}