gpt4 book ai didi

json - 如何使用 Aeson 解析此 JSON?

转载 作者:行者123 更新时间:2023-12-02 07:52:30 25 4
gpt4 key购买 nike

我有以下 JSON 片段:

{
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "broken clouds",
"icon": "04n"
}
],
"main": {
"temp": 271.979,
"pressure": 1024.8,
"humidity": 100,
"temp_min": 271.979,
"temp_max": 271.979,
"sea_level": 1028.51,
"grnd_level": 1024.8
},
"id": 6332485,
"name": "Queensbridge Houses",
"cod": 200
}

我想从中解析以下类型:

data WeatherResponse = WeatherResponse
{ temp :: Double
, humidity :: Double
, weatherMain :: T.Text
} deriving Show

我一直在尝试使用以下代码来执行此操作,但我不断遇到错误。我终于得到了所有类型的匹配,但它解析不正确,并且不真正理解它失败的地方。

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

import Data.Aeson
import Data.Aeson.Types (Parser, Array)
import Data.Time (defaultTimeLocale, formatTime, getZonedTime)

import qualified Data.ByteString.Lazy as BL
import qualified Data.Vector as V
import qualified Data.Text as T

data WeatherResponse = WeatherResponse
{ temp :: Double
, humidity :: Double
, weatherMain :: T.Text
} deriving Show

lambda3 :: Value -> Parser T.Text
lambda3 o = do
withText "main" (\t -> do
return t
) o

parseInner :: Value -> Parser T.Text
parseInner a = withArray "Inner Array" (lambda3 . (V.head)) a

instance FromJSON WeatherResponse where
parseJSON =
withObject "Root Object" $ \o -> do
mainO <- o .: "main"
temp <- mainO .: "temp"
humidity <- mainO .: "humidity"
weatherO <- o .: "weather"
weatherMain <- parseInner weatherO
return $ WeatherResponse temp humidity weatherMain

getSampleData = BL.readFile "/home/vmadiath/.xmonad/weather.json"

main = do
text <- getSampleData
let (result :: Either String WeatherResponse) = eitherDecode text
putStrLn . show $ result

我只是得到以下输出,这并不足以让我知道我哪里出了问题。

$ runhaskell lib/code.hs
Left "Error in $: expected main, encountered Object"

我已将整个内容放在可查看的要点中 here

我想知道代码有什么问题,以及如何修复它。如果您对如何以更具可读性的方式编写此内容有建议,我也很想知道。目前,我主要对两个单独的函数 lambda3 感到恼火,而 parseInner 很烦人)

最佳答案

在我看来,你把事情搞得太复杂了。像这样的东西应该有效:

instance FromJSON WeatherResponse where
parseJSON (Object v) = do
weatherValue <- head <$> v .: "weather"
WeatherResponse <$> ((v .: "main") >>= (.: "temp"))
<*> ((v .: "main") >>= (.: "humidity"))
<*> weatherValue .: "main"

输出:

[nix-shell:~/haskell-sample]$ ./weather
Right (WeatherResponse {temp = 271.979, humidity = 100.0, weatherMain = "Clouds"})

关于json - 如何使用 Aeson 解析此 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35404541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com