2016-02-15 12 views
5

私は、次のJSONスニペットがあります。私はそれから、次の種類の解析を取得したいこのJSONをAesonと解析するにはどうすればよいですか?

{ 
    "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 

私は単に私が間違っていた場所を知るのに十分ではない次の出力を取得します。私はhere

閲覧可能な主旨で全体の事を入れている

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

私はコードで間違っているものを知りたいのですが、どのように私はそれを修正することができます。あなたがこれをもっと読みやすい方法で書く方法の提案があれば、私もそれを知りたいです。現在、私はほとんど別の2つの機能に悩まされていますlambda3parseInnerは厄介です)

+0

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

それは出力です= withObject "weatherMain"(。: "メイン") '。 – zakyggaps

答えて

4

私の意見では、これはあまりにも複雑にしています。このような何か作業をする必要があります:あなたがオブジェクトである `weather`配列の最初の要素を持って、それは` lambda3あるべきV.head` `によって

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