记录的数据验证

时间:2012-11-19 23:56:49

标签: json haskell record aeson lenses

您是否知道任何Haskell库

  1. 为记录验证和(!)
  2. 提供了一些简化
  3. Aeson 合作?
  4. 我知道我可以写一些构造函数但是我想删除样板而不重新发明轮子。

    我正在寻找的是以下内容:

    我想为每个字段定义“合同”。例如:

    data Person = Person {
         age   :: Integer
        ,email :: Text
        ,projects :: [Project]}
    

    现在,我想保证在将JSON解析为记录之后,以下内容成立:

    1. 年龄[0,Inf]
    2. 电子邮件匹配“^ [A-Z0-9 ._%+ - ] + @ [A-Z0-9 .-] +。[A-Z] {2,6} $”
    3. 项目至少包含2个项目
    4. 如果我尝试创建一个年龄<&lt;的记录0,我将收到一条错误消息,例如“0 = inf”中的“age = 0 no”。我假设应该可以通过模板Haskell派生这样的东西。

      此外,我想将其整合到解析器阶段。因此,我不想得到像“当预期的积分,遇到String而不是”时的错误消息,我想得到一条错误消息

      1. 显示错误的位置(不确定是否可以使用attoparsec)
      2. 描述错误。

2 个答案:

答案 0 :(得分:2)

看起来ocharles已经创造了这样一个包! http://hackage.haskell.org/package/digestive-functors-aeson

答案 1 :(得分:0)

在那里,age不是年龄,是Integermail不是邮件,是{ {1}}。

我认为,您应该创建自己的TextAge数据类型,并创建正确的MailToJSON个实例(仅一次)。

例如

FromJSON

现在,使用newtype Age = Age { unAge :: Word8 } deriving (Eq, Generic, Ord, Show) instance Bounded Age where minBound = Age 0 maxBound = Age 150 instance FromJSON Age where parseJSON (Number n) = case (toBoundedInteger n >>= makeAge) of Nothing -> fail $ "The number " ++ show n ++ " is not a valid Age value \ \(must to be between " ++ show (minBound :: Age) ++ " and " ++ show (maxBound :: Age) Just k -> pure k parseJSON o = typeMismatch "Age" o instance ToJSON Age where toJSON = toJSON . unAge

的一个示例记录
Age

当您解析错误时,会正确报告

>  data Test = Test { age :: Age } deriving (Show, Generic)
> instance ToJSON Test
> instance FromJSON Test

另外,如果未提供> eitherDecode "{\"age\": -1}" :: Either String Test Left "The number -1.0 is not a valid Age value (must to be between Age {unAge = 0} and Age {unAge = 150}"

age