2016-05-16 4 views
3

を解析します。課題は、型が必要なデータを含むキーの名前でエンコードされていることです。理論的には私は.:?呼び出しの束を使用して、指定された鍵がJustを返しますが、私はより良い方法が必要だと思うかどうかを確認できます。私はasumを見ましたが、これはあまり役に立たなかったでしょう。アイソーンは、私は複数のコンストラクタでタイプを生成するためにJSONを解析しようとしている複数のコンストラクタに

import Data.Aeson 
import Data.Time.Clock 

data Request = Req1 { id :: String, properties :: Value } 
      | Req2 { id :: String, properties :: Value } 
      | Req3 { id :: String, time :: UTCTime } 

instance FromJSON Request where 
    parseJSON = withObject "message" $ \o -> 
    -- ??? 

例要求:

{"req1": {"id": "345", "p1": "v1", "p2": "v2"}} 

{"req2": {"id": "654", "p3", "v3"}} 

{"req3": {"id": "876", "time": 1234567890}} 
+1

は、各個別のリクエストオブジェクトの異なるタイプを使用することはできませんか? – jkeuhlen

+0

もhttp://stackoverflow.com/questions/32421836/aeson-parsing-dynamic-keys-as-type-field?rq=1見ます –

答えて

2

がここに手動でオブジェクトを検査する方法は次のとおりです。

{-# LANGUAGE OverloadedStrings #-} 

import Data.Aeson 
import Data.Time.Clock 
import qualified Data.HashMap.Strict as H 
import Control.Monad 

type Val = Int 

data Request = Req1 { id :: String, properties :: Val } 
      | Req2 { id :: String, properties :: Val } 
      | Req3 { id :: String, time :: UTCTime } 

instance FromJSON Request where 
    parseJSON (Object v) = 
    case H.lookup "req1" v of 
     Just (Object h) -> Req1 <$> h .: "id" <*> h .: "properties" 
     Nothing -> 
     case H.lookup "req2" v of 
      Just (Object h) -> Req2 <$> h .: "id" <*> h .: "properies" 
      Nothing -> 
      case H.lookup "req3" v of 
       Just (Object h) -> Req3 <$> h .: "id" <*> h .: "time" 
       Nothing -> mzero 

キーreq1はそれはそれはREQ1値であると仮定します存在している場合。そうでない場合は、キーreq2が存在する場合、それをReq2値として解析しようとします。 req3の場合など。これらのキーが存在しない場合、失敗します。

代わりのmzeroあなたはまた、カスタムエラーメッセージを表示するためにfail "..."を使用することができます。

関連する問題