我正在尝试解析形式为的嵌入式JSON
{
"foo":"bar",
"baz":"{"somekey":"someval"}"
}
伊森在哈斯克尔。以下是我的类型:
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}
显然,BaseType
的FromJSON
实例不起作用,因为它将其视为Value String
,而不是更多的JSON供其解析。我试图在我的FromJSON BaseType
实例中找到一种使用decodeEither
的方法,但这需要我做一些黑魔法来从String
转换为ByteString
,我觉得必须有一种更整洁的方法,可能与withEmbeddedJSON
有关。
我如何才能使其正确工作?
我想它会是这样的(未经测试(:
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}