2012-11-19 5 views
2

당신은데이터 유효성 검사

  1. 가 기록 검증아이손에 (!)
  2. 작품에 대한 몇 가지 단순화를 제공하는 모든 하스켈 라이브러리를 알고 있습니까?

나는 몇 가지 생성자 함수를 작성할 수 있지만 바퀴를 다시 만들지 않고 보일러 플레이트를 지우고 싶습니다.

내가 무엇을 찾고 있어요 것은 다음

나는 각 필드에 대해 "계약"을 정의하고 싶습니다. 예를 들어 :

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

지금, 나는 내가 기록으로 JSON을 구문 분석 한 후 그 보장하고자, 다음 원하는 분야

  1. [0, Inf를)
  2. 이메일 경기에서 세 "^[A-Z0-9 ._ % + -]. + @ [A-Z0-9가 .-] + [AZ는 {2,6}는 $ "는
  3. 프로젝트에 포함 된 적어도 2 개의 프로젝트

ag를 사용하여 레코드를 만들려고하면 e < 0, "age = 0 no in [0, inf]"와 같은 오류 메시지가 표시됩니다. 나는 이것이 Haskell 템플릿을 통해 파생 될 수 있어야한다고 가정합니다.

또한, 이것을 파서 단계에 통합하려고합니다. "필수, 발생 문자열 대신 예상 한"

  1. 오류 (확실하지의 위치를 ​​보여줍니다 따라서, 대신 같은 오류 메시지를 받고, 나는이 attoparsec 가능한 경우 오류 메시지가 표시 싶습니다)
  2. 오류를 설명합니다.
+0

"스마트 생성자" – luqui

+0

@luqui : Thx - 이것을 염두에 두라도 스마트 생성자를 Aeson에 쉽게 통합 할 수있는 방법을 찾지 못했습니다. 렌즈. – Chronos

+0

Aeson이 오류가 발생한 위치를보고하지 않는다는 문제가 Monad가 도움이되는 생성자를 반환하는 것처럼 보입니다. 고마워, 루키. 힌트. – Chronos

답변

0

age시대 아닌, IntegermailText메일입니다하지 않습니다.

나는 당신이 당신의 자신의 AgeMail 데이터 유형을 생성하고 (한 번만) 적절한 ToJSONFromJSON 인스턴스를 생성해야한다 생각합니다.age이 아닌 경우 오류로 해석 할 때에,

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}" 

도 제대로보고 제공된

> eitherDecode "{\"age1\": 12}" :: Either String Test 
Left "The key \"age\" was not found"