2016-06-16 12 views
3

の不適切な順序を与え、私はJSONにデータ型をエンコードしようとしています:ハスケル - アイソーンでJSONを生成するフィールド

λ: encode test 
λ: "{\"Asia\":\"3\",\"Period\":\"2013\",\"Africa\":\"1\",\"Americas\":\"2\"}" 

を生成した理由を私は理解していない:与え

{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE RecordWildCards #-} 

import Data.Aeson 

data Trend = Trend 
      { period :: String 
      , africa :: String 
      , americas :: String 
      , asia :: String 
      } deriving Show 

instance ToJSON Trend where 
    toJSON Trend{..} = 
    object [ "Period" .= period 
      , "Africa" .= africa 
      , "Americas" .= americas 
      , "Asia"  .= asia 
      ] 

test = Trend {period = "2013", africa = "1", americas = "2", asia = "3"} 

JSONには、自分のデータ型と同じ順序のフィールドがありません。

私は出力が

私は全体の情報を渡すことで、順序は重要ではないことを理解{期間、アフリカ、アメリカ、アジア}と私は取得しています{アジア、期間、アフリカ、米州)であることを期待していますなぜこれが起こっているのか不思議です。

+7

JSONを使用して価値があるフィールドのない「正しい」順序を持っていません。編集:回答を見る[ここ](http://stackoverflow.com/questions/3948206/json-order-mixed-up) – pdexter

答えて

4

の方法はaeson-0.10(利用可能であればaeson-0.11を使用)から利用できます。その場合、あなたは、生成された構造をより詳細に制御があります:シンプルがこれですと、

instance ToJSON Trend where 
    toJSON Trend{..} = 
    object [ "Period" .= period 
      , "Africa" .= africa 
      , "Americas" .= americas 
      , "Asia"  .= asia 
      ] 

    toEncoding Trend {..} = 
    pairs $ "Period" .= period 
     <> "Africa" .= africa 
     <> "Americas" .= americas 
     <> "Asia"  .= asia 

またはケース内をGeneric派生

instance ToJSON Trend where 
    parseJSON = genericToJSON defaultOptions { fieldLabelModifier = capitaliseFirst } 
     where 
     capitaliseFirst (x:xs) = toUpper x : xs 
     capitaliseFirst []  = [] 
+0

ありがとう、しかし私はちょっと混乱しています。 'enter code here'という行に何かを置くべきですか? – matthias

+0

ああ、それはinlneのエディタによって紹介されたものです:S – phadej

+0

'toEncoding'を使うために特定のプラグマをロードする必要がありますか?私はスコープに含まれていない "シリーズ"を取得し、アイソンに固有の '<>'ですか? – matthias

3

Aesonオブジェクトが単なるHashMapであるため、aesonがHashMapをテキストに変換すると、HashMapから返された順序でキーと値のペアがシリアル化されます。おそらく関係はありませんキーが挿入された順序