parsing - 如何在使用 Data.Aeson 解析 JSON 时正确出错

标签 parsing haskell monads applicative aeson

我的类型和对应的 FromJSON 实现如下所示。
nonEmpty变成 List变成 Maybe NonEmpty我正在尝试正确处理 List 的情况确实是空的,我必须中止解析。这个解析实际上是在 parseJsonBody 内部完成的。 ,这意味着我不想 error "foo"我的出路,但我想返回mzero (或者其他任何可以解决问题的方法,mzero 是我迄今为止偶然发现的唯一东西)以便处理程序正确返回 400 而不是以 500 崩溃。

下面的方法可以编译,但据我所知几乎等于 error或在 parseJSON 中抛出某种其他形式的异常。如果我返回 mzero但是(例如,使用 <*> mzero 而不是该行),它按预期很好地失败了。

import qualified Data.List.NonEmpty as NE
data GSAnswer = GSAnswer { gsAnswerQuestionId :: Int
                         , gsAnswerResponses :: NE.NonEmpty GSResponse
                         } deriving (Show, Eq)


instance FromJSON GSAnswer where
  parseJSON (Object o) =
    GSAnswer <$> o .: "question-id"
             -- how do I return mzero here based on NE.nonEmpty?
             -- this will throw an exception right now on an empty list
             <*> fmap (fromMaybe (fail "foo") . NE.nonEmpty) (o .: "responses")
  parseJSON _ = mzero

一种选择是以某种方式对 fmap NE.nonEmpty (o .: "responses") 的结果进行模式匹配。 ,但我不太清楚那里的模式是什么:看起来 Parser 没有任何构造函数?

最佳答案

本质上,您需要一个 Parser [a] -> Parser NE.NonEmpty变压器,比较简单:

-- toNonEmptyP :: Parser [a] -> Parser NE.NonEmtpy
toNonEmptyP p = fmap NE.nonEmpty p >>= maybe mzero return

我们 map NE.nonEmpty在我们的常规列表解析器上,它给了我们 Parser (Maybe NE.NonEmpty) .然后我们检查 Maybemaybe或者使用 mzero如果是 Nothing , 或 return解析后的值返回到解析上下文。您的 FromJSON实例然后归结为
instance FromJSON GSAnswer where
  parseJSON (Object o) =
    GSAnswer <$> o .: "question-id"
             <*> toNonEmptyP (o .: "responses")
  parseJSON _ = mzero

您可以使用 fail msg而不是 mzero提供自定义错误消息,如 fail :: String -> Parser a没有触底。

关于parsing - 如何在使用 Data.Aeson 解析 JSON 时正确出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28494209/

相关文章:

haskell - Monads如何被认为是纯的?

haskell - 我怎样才能继续实现这个monad转换器?

java - 在 java 中为 Android 应用程序解析 html

haskell - Maybe 应该用来保存错误消息吗?

java - 如何在java中打开文件并解析每一行

haskell - 如何理解Haskell中的 "(Num b) => length::[a] -> b"?

unit-testing - 如何测试 Haskell 中的错误?

haskell - 函数应用作为身份 Monad : how is it an instance of the Monad typeclass?

javascript - Google map API 页面未加载 - 解析 XML 错误

java - 使用 DOM 解析复杂的 XML