Проблема в том, что aeson ищет в файле поле с именем mainInfo , но такого поля не существует.
Сначала я думал, что мы могли быустранить проблему, изменив mainInfo в определении типа для MainWeatherInfo на main .Это не сработает, потому что функция с таким именем уже существует!
aeson предоставляет выход из этого, и вы можете найти описание в этот полезный урок в разделе Generics: настройка имен полей .
Просто чтобы быть более конкретным, если вы используете метод turorial, вы получите Main.hs , который выглядит следующим образом:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
module Main where
import GHC.Generics
import Data.Aeson
import Data.Aeson.Types
import qualified Data.ByteString as L
data MainWeatherInfo = MainWeatherInfo
{ mainInfo :: Main
} deriving ( Show
, Generic
)
instance ToJSON MainWeatherInfo where
toJSON = genericToJSON defaultOptions { fieldLabelModifier = take 4 }
instance FromJSON MainWeatherInfo where
parseJSON = genericParseJSON defaultOptions { fieldLabelModifier = take 4 }
data Main = Main
{ temp :: Double
, pressure :: Int
, humidity :: Int
, temp_min :: Double
, temp_max :: Double
} deriving ( Show
, Generic
, ToJSON
, FromJSON
)
main :: IO ()
main = do
contents <- L.readFile "notes/test.json"
let result = (decodeStrict contents) :: Maybe MainWeatherInfo
case result of
Nothing -> putStrLn "error"
Just v -> putStrLn $ show v
Я попробовал его на своем компьютере, и он работал нормально.
ОБНОВЛЕНИЕ: Я был очень глупыми предположил, что решение должно быть ограничено только одним модулем.Вероятно, было бы намного лучше иметь Main.hs , который выглядит как:
module Main where
import Data.Aeson
import qualified Data.ByteString as L
import qualified Weather as W
main :: IO ()
main = do
contents <- L.readFile "notes/test.json"
let result = (decodeStrict contents) :: Maybe W.MainWeatherInfo
case result of
Nothing -> putStrLn "error"
Just v -> putStrLn $ show v
, а также другой модуль Weather.hs то есть:
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-}
module Weather where
import GHC.Generics
import Data.Aeson
import Data.Aeson.Types
data MainWeatherInfo = MainWeatherInfo
{ main :: Main
} deriving ( Show
, Generic
, ToJSON
, FromJSON
)
data Main = Main
{ temp :: Double
, pressure :: Int
, humidity :: Int
, temp_min :: Double
, temp_max :: Double
} deriving ( Show
, Generic
, ToJSON
, FromJSON
)
Я проверил это, просто чтобы убедиться, и оно работает.