【问题标题】:Aeson fromJSON instanceAeson fromJSON 实例
【发布时间】:2011-09-02 00:32:31
【问题描述】:

我有以下数据类型:

 data User = User { name :: T.Text, bookCount :: Int ,memberSince :: DateTime ,
  email :: T.Text, password :: B.ByteString } 
  | UnverifiedUser { nameUnverified :: T.Text,   emailUnverified :: T.Text,
     secret :: Integer  }

还有以下实例:

instance FromJSON User where
    parseJSON (Object o) | Just _ <- M.lookup "secret" o = UnverifiedUser <$> o .: "name" <*> o .: "email" <*> o .: "secret"
                         | otherwise = User <$>  o .: "name" <*>  o .: "bookCount" <*> o .: "memberSince" <*> o .: "email" <*> o .: "password"
    parseJSON _          = mzero

但是 User 被分成了两个,因为有时 couchdb 中的文档没有一些字段,如 secret 或 password。 如何为数据类型创建 fromJSON 实例:

   data User = User { name :: T.Text, bookCount :: Int ,memberSince :: DateTime ,
      email :: T.Text, password :: B.ByteString , secret :: Integer  }

有些字段是强制性的,有些则不是?

【问题讨论】:

  • 您知道相同数据类型的不同构造函数可以共享记录字段名称(前提是它们也共享记录字段类型)?对于你的例子,你可以写data User = Verified { name :: T.Text, email :: T.Text, ... } | Unverified { name :: T.Text, email :: T.Text }
  • @Daniel:虽然这是正确的,但通常更容易在一种数据类型中包含共同的内容并将不同的内容拆分为另一种:data User = User { name :: T.Text, email :: T.Text, verification :: Verification }data Verification = Unverified { secret :: Integer } | Verified { memberSince :: DateTime, password :: T.Text }
  • @Daniel,不,我没有。但我不相信未经验证的用户足以接受他的名字作为验证。
  • @Hai 我不确定我是否理解信任与数据类型定义之间的联系。

标签: json haskell


【解决方案1】:

为什么不使用Maybe

 data User =
   User {
     name            :: T.Text,
     bookCount       :: Int ,
     memberSince     :: DateTime ,
     email           :: T.Text,
     password        :: Maybe B.ByteString,
     nameUnverified  :: T.Text,
     emailUnverified :: T.Text,
     secret          :: Maybe Integer}

instance FromJSON User where
    parseJSON (Object o) = User <$>
         o .: "name"            <*>
         o .: "bookCount"       <*>
         o .: "memberSince"     <*>
         o .: "email"           <*>
         o .:? "password"       <*>
         o .: "nameUnverified"  <*>
         o .: "emailUnverified" <*>
         o .:? "secret"

【讨论】:

  • 我最终做了一些不同的事情,但无论如何都可以使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-06
相关资源
最近更新 更多