Haskell Aeson具有数组的数组,其中一些是空的
我有不幸的数据要处理:Haskell Aeson具有数组的数组,其中一些是空的,haskell,aeson,Haskell,Aeson,我有不幸的数据要处理: { "name": "foo" , "data": [ [] , ["a", "b", "c", 1] , ["d", "e", "f", 2] ] } 数据项可以是空数组,也可以是大小为4的数组 我想解析为: data ResultRow = ResultRow Text Text Text Int deriving (Show, Generic) data ResultSet = ResultSet { f_name :
{ "name": "foo"
, "data": [ []
, ["a", "b", "c", 1]
, ["d", "e", "f", 2] ] }
数据项可以是空数组,也可以是大小为4的数组
我想解析为:
data ResultRow = ResultRow Text Text Text Int deriving (Show, Generic)
data ResultSet =
ResultSet { f_name :: Text
, f_data :: [Maybe ResultRow] } deriving (Show, Generic)
但是,以下内容不接受空数组:
customOptions = defaultOptions { fieldLabelModifier = drop 2 }
instance FromJSON ResultRow where
parseJSON = genericParseJSON customOptions
instance FromJSON ResultSet where
parseJSON = genericParseJSON customOptions
错误消息是:
Left "Error in $[1].data[0]: When expecting a product of 4 values, encountered an Array of 0 elements instead"
我还尝试在[可能是ResultRow]
周围添加一个额外的类型,将子数组转换为[]
上的列表和模式匹配,并将非空的大小写分派给ResultRow
解析器,但我无法编译它,并在错误消息中丢失
理想情况下,我希望有一些跳过空数组的方法,因为它们只是数据中的噪声。我无法控制数据的产生者。像dsvensson一样,我感到困惑的是,这并不是开箱即用的,因为[a]
和可能a
都是来自JSON
的实例,而a
是。因为我已经在这上面花费了太多的时间,我不能提供一个解释,但我可以提供一个解决方法。希望更有知识的人能给出更好的答案
您可以定义一个包装Maybe ResultRow
的newtype
,而不是将f\u数据定义为[Maybe ResultRow]
:
newtype MaybeResultRow = MaybeResultRow (Maybe ResultRow) deriving (Show, Generic)
您可以从JSON中为该类型指定特殊的行为:
instance FromJSON MaybeResultRow where
parseJSON v =
case fromJSON v of
Success rr -> return $ MaybeResultRow $ Just rr
_ -> return $ MaybeResultRow Nothing
这显然意味着ResultSet
的更改:
data ResultSet =
ResultSet { f_name :: Text
, f_data :: [MaybeResultRow] } deriving (Show, Generic)
为了进行测试,我定义了以下JSON文档:
myJson :: ByteString
myJson =
"{\
\\"name\": \"foo\",\
\\"data\": [\
\[],\
\[\"a\", \"b\", \"c\", 1],\
\[\"d\", \"e\", \"f\", 2]\
\]\
\}"
将其全部加载到GHCi中,看起来它正在工作:
*Lib Lib> decode myJson :: Maybe ResultSet
Just (ResultSet {
f_name = "foo"
, f_data = [
MaybeResultRow Nothing,
MaybeResultRow (Just (ResultRow "a" "b" "c" 1)),
MaybeResultRow (Just (ResultRow "d" "e" "f" 2))]})
在这里,我自由地格式化了GHCi的输出,以增强可读性
我相信您能够找到如何展开和过滤MaybeResultRow
值列表的方法
我偷了使用json的和匹配成功的解决方案。在这种情况下,我不会使用通用json解析器,而是使用aeson的组合器自己编写!您是说这在通用json解析器中是不可能/不可行的,还是说您不知道如何做到这一点,因此在注释中而不是答案中推荐组合符?您是否有任何阅读材料建议使用您提到的组合词来探索与我类似的数据?请尝试使用[ResultRow]而不是[Maybe ResultRow]