{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} --needed for ByteString arguments module DataTypes where import Data.Aeson import GHC.Generics import qualified Data.ByteString.Lazy.Char8 as BL data Location = Location { name :: String , region :: String , country :: String , lat :: Float , lon :: Float , tz_id :: String , localtime_epoch :: Int , localtime :: String } deriving (Show, Generic) data Current = Current { temp_c :: Float } deriving (Show, Generic) data Day = Day { avgtemp_c :: Float } deriving (Show, Generic) data ForecastDay = ForecastDay { day :: Day } deriving (Show, Generic) data Forecast = Forecast { forecastday :: [ForecastDay] } deriving (Show, Generic) data WeatherResponse = WeatherResponse { location :: Location , current :: Maybe Current , forecast :: Maybe Forecast } deriving (Show, Generic) instance FromJSON Location instance ToJSON Location instance FromJSON Current instance ToJSON Current instance FromJSON Day instance ToJSON Day instance FromJSON ForecastDay instance ToJSON ForecastDay instance FromJSON Forecast instance ToJSON Forecast instance FromJSON WeatherResponse instance ToJSON WeatherResponse weatherDecode :: BL.ByteString -> IO WeatherResponse weatherDecode jsonBody = case decode jsonBody :: Maybe WeatherResponse of Just decoded -> return decoded Nothing -> error "Invalid JSON" getTemperature :: WeatherResponse -> Float getTemperature (WeatherResponse _ Nothing Nothing) = error "No data provided!" getTemperature (WeatherResponse _ (Just curr) Nothing) = getTemperatureFromCurrent curr getTemperature (WeatherResponse _ Nothing (Just fore)) = getTemperatureFromForecastDay $ getForecastDayFromForecast fore getTemperature (WeatherResponse _ (Just _) (Just fore)) = getTemperatureFromForecastDay $ getForecastDayFromForecast fore getForecastDayFromForecast :: Forecast -> ForecastDay getForecastDayFromForecast (Forecast forecasts) = head forecasts getTemperatureFromCurrent :: Current -> Float getTemperatureFromCurrent (Current temp) = temp getTemperatureFromForecastDay :: ForecastDay -> Float getTemperatureFromForecastDay (ForecastDay (Day temp)) = temp