Это работает отлично! Спасибо!

историческими данными» я имею в виду даты в качестве ключа, а значение в этот день в качестве значения.

Например, часто правительственные институты или исследовательский отдел университета собирают данные о землетрясениях, ливнях, движении рынка и т. Д. В этом формате

 {
        "Meta Data": {
            "1: Country": "SomeCountry",
            "2: Region": "SomeRegion",
            "3: Latest Recording": "2018-11-16"
        },
        "EarthQuakes": {
            "2018-11-16": {
                "Richter": "5.2508"
            },
            "2018-11-09": {
                "Richter": "4.8684"
            },
            "2018-11-02": {
                "Richter": "1.8399"
            },
    ...
    ...
    ...
            "1918-11-02": {
                "Richter": "1.8399"
            }
}

Обычно это будет раздел «Метаданные», а другой будет содержать значения / данные.

Я, как новичок, знаю два способа разбора документов такого типа.

Либо вы идете с общим анализом, показанным в документации Aeson, где вы определяете типы данных, как это

Data MetaData = MetaData { country :: String, region :: String, latestRec :: String } deriving (Show, Eq, Generic)

Сделайте это экземпляромFromJSON

instance FromJSON MetaData where
  parseJSON = withObject "MetaData" $
    \v -> do
       metaData  <- v        .: pack "Meta Data"
       country   <- metaData .: pack "1: Country"
       region    <- metaData .: pack "2: Region"
       latestRec <- metaData .: pack "3: Latest Recording"
       return MetaData{..}

С конечноRecordWildCard а такжеDeriveGenerics Расширения включены.

Проблема, которую я вижу с этим подходом, состоит в том, что он не может быть легко реализован для раздела «EarthQuakes».

Я должен определить каждую дату

earthQuakes <- v .: "EarthQuakes"
date1 <- earthQuakes .: "2018-11-16"
date2 <- earthQuakes .: "2018-11-06"
date3 <- earthQuakes .: "2018-11-02"
...
...
dateInfinity <- earthQuakes .: "1918-11-16"

Лучшим подходом было бы просто проанализировать все данные как значения JSON по умолчанию, расшифровав ссылку вObject тип

thisFunction = do
    linksContents <- simpleHttp "somelink"
    let y = fromJust (decode linksContents :: Object)
        z = aLotOfFunctionCompositions y
    return z

гдеaLotOfFunctionCompositions будет сначала преобразоватьObject может бытьHashMap имеющий[(k, v)] пар. Тогда я бы на картуunConstruct функция, чтобы получить значение из конструкторов по умолчанию, таких как

unConstruct (DefaultType value) = case (DefaultType value) of
             DefaultType x -> x

и, наконец, вы получите хороший список!

Проблема с этим подходом заключается вaLotOfFunctionComposition.

Это всего лишь пример! Но на самом деле это может выглядеть так же безобразно и нечитаемо, как эта

let y = Prelude.map (\(a, b) -> (decode (encode a) :: Maybe String, decode (encode (snd (Prelude.head b))) :: Maybe String)) x
      z = Prelude.map (\(a, b) -> (fromJust a, fromJust b)) y
      a = Prelude.map (\(a, b) -> (a, read b :: Double)) z
      b = Prelude.map (\(a, b) -> (Prelude.filter (/= '-') a, b)) a
      c = Prelude.map (\(a, b) -> (read a :: Int, b)) b

Это фрагмент из рабочего кода, который я сделал.

Итак, мой вопрос заключается в следующем: есть ли лучший / более чистый способ декодирования таких JSON-файлов, где у вас много ключей «даты», и вам нужно проанализировать их в работающие типы данных?

Ответы на вопрос(1)

Ваш ответ на вопрос