diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,10 @@
+0.2.0
+=====
+
+  * (* BREAKING *) Made Location a part of the API to
+    reduce code duplication.
+
+
 0.1.0
 =====
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -22,16 +22,19 @@
 -----
 
 ```
-Usage: openweathermap ([-K|--api-key-file APIKEYFILE] | [-k|--api-key APIKEY])
-                      ((-c|--city CITY) | --lat NUM --lon NUM) [-d|--debug]
+Usage: openweathermap [(-K|--api-key-file APIKEYFILE) | (-k|--api-key APIKEY)]
+                      ((-q|--query STRING) | --lat NUM --lon NUM)
+                      [(-n|--current) | (-f|--forecast)] [-d|--debug]
 
 Available options:
   -K,--api-key-file APIKEYFILE
                            Read API key from this file
   -k,--api-key APIKEY      API key
-  -c,--city CITY           City name
+  -q,--query STRING        City name, e. g. Santiago or Santiago,CU
   --lat NUM                Latitude in decimal degrees
   --lon NUM                Longitude in decimal degrees
+  -n,--current             current weather (default)
+  -f,--forecast            forecast weather
   -d,--debug               Enable debug
   -h,--help                Show this help text
 
@@ -46,11 +49,36 @@
 --------
 
 ```
-$ openweathermap -c norilsk
+$ openweathermap -q norilsk
 Norilsk,RU (69.35°, 88.2°): Clouds,  H 100 %,  P 753 mmHg,  T +4 °C,  ↓ 1 m/s
 
 $ openweathermap --lat 55.7522200 --lon 37.6155600
 Moscow,RU (55.75°, 37.62°): Clear,  H 45 %,  P 762 mmHg,  T +18..+21 °C,  → 4 m/s
+
+$ openweathermap -q kaliningrad -f
+Kaliningrad,RU (54.7065°, 20.511°)
+2020-04-19 17:00:00 +0200: Clear, H 66 %, P 767 mmHg, T +7 °C, ↓ 7 m/s
+2020-04-19 20:00:00 +0200: Clear, H 79 %, P 768 mmHg, T +4 °C, ↓ 5 m/s
+2020-04-19 23:00:00 +0200: Clear, H 84 %, P 769 mmHg, T +3 °C, ↓ 4 m/s
+2020-04-20 02:00:00 +0200: Clear, H 85 %, P 770 mmHg, T +3 °C, ↓ 3 m/s
+2020-04-20 05:00:00 +0200: Clear, H 84 %, P 770 mmHg, T +2 °C, ↓ 3 m/s
+2020-04-20 08:00:00 +0200: Clear, H 76 %, P 770 mmHg, T +5 °C, ↓ 4 m/s
+2020-04-20 11:00:00 +0200: Clear, H 65 %, P 771 mmHg, T +8 °C, ↓ 4 m/s
+2020-04-20 14:00:00 +0200: Clear, H 62 %, P 771 mmHg, T +9 °C, ↓ 4 m/s
+...
+
+$ openweathermap --lat -12.0432 --lon -77.0282 -f
+Lima,PE (-12.0432°, -77.0282°)
+2020-04-19 10:00:00 -0500: Clear, H 70 %, P 764 mmHg, T +22..+24 °C, ↗ 3 m/s
+2020-04-19 13:00:00 -0500: Clear, H 64 %, P 762 mmHg, T +23..+25 °C, ↗ 4 m/s
+2020-04-19 16:00:00 -0500: Clouds, H 66 %, P 761 mmHg, T +23..+24 °C, ↑ 4 m/s
+2020-04-19 19:00:00 -0500: Clouds, H 72 %, P 763 mmHg, T +22 °C, ↑ 4 m/s
+2020-04-19 22:00:00 -0500: Clouds, H 72 %, P 764 mmHg, T +22 °C, ↑ 3 m/s
+2020-04-20 01:00:00 -0500: Clouds, H 76 %, P 763 mmHg, T +21 °C, ↑ 2 m/s
+2020-04-20 04:00:00 -0500: Clear, H 80 %, P 763 mmHg, T +20 °C, ↑ 3 m/s
+2020-04-20 07:00:00 -0500: Clouds, H 79 %, P 764 mmHg, T +20 °C, ↑ 3 m/s
+2020-04-20 10:00:00 -0500: Clouds, H 72 %, P 764 mmHg, T +21 °C, ↗ 3 m/s
+...
 ```
 
 
diff --git a/cmd/Main.hs b/cmd/Main.hs
--- a/cmd/Main.hs
+++ b/cmd/Main.hs
@@ -5,7 +5,6 @@
   ) where
 
 import Control.Monad (when)
-import Data.List (intercalate)
 import Data.Semigroup ((<>))
 import Data.Version (showVersion)
 import System.Exit (die)
@@ -17,6 +16,7 @@
   , (<|>)
   , auto
   , execParser
+  , flag'
   , fullDesc
   , header
   , help
@@ -33,26 +33,25 @@
 import System.Directory (createDirectoryIfMissing)
 import System.Environment.XDG.BaseDir (getUserConfigDir, getUserConfigFile)
 
-import Paths_openweathermap (version) -- from cabal
 import qualified Web.OpenWeatherMap.Client as Client
-import qualified Web.OpenWeatherMap.Types.Coord as Coord
-import qualified Web.OpenWeatherMap.Types.CurrentWeather as CurrentWeather
-import qualified Web.OpenWeatherMap.Types.Main as Main
-import qualified Web.OpenWeatherMap.Types.Sys as Sys
-import qualified Web.OpenWeatherMap.Types.Weather as Weather
-import qualified Web.OpenWeatherMap.Types.Wind as Wind
+import Web.OpenWeatherMap.Types.Location (Location(..))
 
+import Paths_openweathermap (version) -- from cabal
+import Print (printCurrectWeather, printForecastWeather)
+
 appName :: String
 appName = "openweathermap"
 
-parseLocation :: Parser Client.Location
+parseLocation :: Parser Location
 parseLocation = byName <|> byCoord
   where
     byName =
-      Client.Name <$>
-      strOption (long "city" <> short 'c' <> metavar "CITY" <> help "City name")
+      Name <$>
+      strOption
+        (long "query" <> short 'q' <> metavar "STRING" <>
+         help "City name, e. g. Santiago or Santiago,CU")
     byCoord =
-      Client.Coord <$>
+      Coord <$>
       option
         auto
         (long "lat" <> metavar "NUM" <> help "Latitude in decimal degrees") <*>
@@ -77,15 +76,29 @@
       strOption
         (long "api-key" <> short 'k' <> metavar "APIKEY" <> help "API key")
 
-data Config = Config
-  { apikey :: Maybe ApiKey
-  , location :: Client.Location
-  , debug :: Bool
-  }
+data Weather
+  = Current
+  | Forecast
 
+parseWeather :: Parser Weather
+parseWeather =
+  flag'
+    Current
+    (long "current" <> short 'n' <> help "current weather (default)") <|>
+  flag' Forecast (long "forecast" <> short 'f' <> help "forecast weather") <|>
+  pure Current
+
+data Config =
+  Config
+    { apikey :: Maybe ApiKey
+    , location :: Location
+    , weather :: Weather
+    , debug :: Bool
+    }
+
 parseConfig :: Parser Config
 parseConfig =
-  Config <$> optional parseApiKey <*> parseLocation <*>
+  Config <$> optional parseApiKey <*> parseLocation <*> parseWeather <*>
   switch (long "debug" <> short 'd' <> help "Enable debug")
 
 getApiKey :: Maybe ApiKey -> IO String
@@ -95,93 +108,22 @@
   createDirectoryIfMissing True =<< getUserConfigDir appName
   getUserConfigFile appName "key" >>= getApiKey . Just . ApiKeyFile
 
-showLocation :: CurrentWeather.CurrentWeather -> String
-showLocation w = city ++ maybe "" ("," ++) country ++ " " ++ coords
-  where
-    name = CurrentWeather.name w
-    coord = CurrentWeather.coord w
-    country = Sys.country . CurrentWeather.sys $ w
-    city =
-      if name /= ""
-        then name
-        else "<unknown>"
-    coords =
-      "(" ++ show (Coord.lat coord) ++ "°, " ++ show (Coord.lon coord) ++ "°)"
-
-showWeather :: [Weather.Weather] -> String
-showWeather w = intercalate "," $ Weather.main <$> w
-
-showHumidity :: Main.Main -> String
-showHumidity m = "H " ++ show hm ++ " %"
-  where
-    hm :: Int
-    hm = round . Main.humidity $ m
-
--- https://en.wikipedia.org/wiki/Millimeter_of_mercury
-showPressure :: Main.Main -> String
-showPressure m = "P " ++ show p ++ " mmHg"
-  where
-    hPa2mmHg hpa = hpa * 0.750061561303
-    p :: Int
-    p = round . hPa2mmHg . Main.pressure $ m
-
--- https://stackoverflow.com/q/7490660/933161
-showWind :: Wind.Wind -> String
-showWind w = dir ++ " " ++ show speed ++ " m/s"
-  where
-    speed :: Int
-    speed = round . Wind.speed $ w
-    deg = Wind.deg w
-    --     [ "N", "NE", "E", "SE", "S", "SW", "W", "NW" ]
-    dirs = ["↓", "↙", "←", "↖", "↑", "↗", "→", "↘"]
-    l = length dirs
-    sector = round $ (deg * fromIntegral l) / 360.0
-    dir = dirs !! (sector `rem` l)
-
-showTemp :: Main.Main -> String
-showTemp m = "T " ++ temp ++ " °C"
-  where
-    k2c k = k - 273.15 -- Kelvin to Celsius
-    tmax :: Int
-    tmin :: Int
-    tmax = round . k2c . Main.temp_max $ m
-    tmin = round . k2c . Main.temp_min $ m
-    show' t =
-      if t > 0
-        then "+" ++ show t
-        else show t
-    temp =
-      if tmax /= tmin
-        then show' tmin ++ ".." ++ show' tmax
-        else show' tmin
-
-printWeather :: CurrentWeather.CurrentWeather -> IO ()
-printWeather w = putStrLn out
-  where
-    weather = showWeather $ CurrentWeather.weather w
-    place = showLocation w
-    mainw = CurrentWeather.main w
-    wind = CurrentWeather.wind w
-    out =
-      place ++
-      ": " ++
-      intercalate
-        ",  "
-        [ weather
-        , showHumidity mainw
-        , showPressure mainw
-        , showTemp mainw
-        , showWind wind
-        ]
-
 run :: Config -> IO ()
 run cfg = do
   appid <- getApiKey . apikey $ cfg
-  Client.getWeather appid (location cfg) >>= \case
-    Left err -> die $ show err
-    Right weather -> do
-      when (debug cfg) $ hPrint stderr weather
-      printWeather weather
+  case weather cfg of
+    Current ->
+      Client.getWeather appid (location cfg) >>= \case
+        Left err -> die $ show err
+        Right cw -> do
+          when (debug cfg) $ hPrint stderr cw
+          printCurrectWeather cw
+    Forecast ->
+      Client.getForecast appid (location cfg) >>= \case
+        Left err -> die $ show err
+        Right fw -> do
+          when (debug cfg) $ hPrint stderr fw
+          printForecastWeather fw
 
 main :: IO ()
 main = run =<< execParser opts
diff --git a/cmd/Print.hs b/cmd/Print.hs
new file mode 100644
--- /dev/null
+++ b/cmd/Print.hs
@@ -0,0 +1,125 @@
+module Print
+  ( printCurrectWeather
+  , printForecastWeather
+  ) where
+
+import Data.List (intercalate)
+import Data.Time.Clock.POSIX (posixSecondsToUTCTime)
+import Data.Time.LocalTime (TimeZone, minutesToTimeZone, utcToZonedTime)
+
+import qualified Web.OpenWeatherMap.Types.City as City
+import qualified Web.OpenWeatherMap.Types.Coord as Coord
+import qualified Web.OpenWeatherMap.Types.CurrentWeather as CW
+import qualified Web.OpenWeatherMap.Types.Forecast as FC
+import qualified Web.OpenWeatherMap.Types.ForecastWeather as FW
+import qualified Web.OpenWeatherMap.Types.Main as Main
+import qualified Web.OpenWeatherMap.Types.Sys as Sys
+import qualified Web.OpenWeatherMap.Types.Weather as Weather
+import qualified Web.OpenWeatherMap.Types.Wind as Wind
+
+printCurrectWeather :: CW.CurrentWeather -> IO ()
+printCurrectWeather cw =
+  putStrLn
+    (place ++
+     ": " ++
+     intercalate
+       ",  "
+       [ w
+       , showHumidity mainw
+       , showPressure mainw
+       , showTemp mainw
+       , showWind wind
+       ])
+  where
+    w = showWeather $ CW.weather cw
+    place = showLocation (CW.name cw) (Sys.country . CW.sys $ cw) (CW.coord cw)
+    mainw = CW.main cw
+    wind = CW.wind cw
+
+printForecastWeather :: FW.ForecastWeather -> IO ()
+printForecastWeather fw = do
+  let c = FW.city fw
+      tz = minutesToTimeZone (City.timezone c `div` 60)
+      place = showLocation (City.name c) (City.country c) (City.coord c)
+  putStrLn place
+  mapM_ putStrLn (showForecast tz <$> FW.list fw)
+
+showForecast :: TimeZone -> FC.Forecast -> String
+showForecast tz fc =
+  localtime ++
+  ": " ++
+  intercalate
+    ", "
+    [ showWeather (FC.weather fc)
+    , showHumidity mainw
+    , showPressure mainw
+    , showTemp mainw
+    , showWind (FC.wind fc)
+    ]
+  where
+    localtime =
+      show . utcToZonedTime tz . posixSecondsToUTCTime . fromIntegral $ FC.dt fc
+    mainw = FC.main fc
+
+showLocation :: String -> Maybe String -> Coord.Coord -> String
+showLocation name country coord =
+  name' ++ maybe "" ("," ++) country ++ " " ++ coords
+  where
+    coords = showCoord coord
+    name' =
+      if name /= ""
+        then name
+        else "<unknown>"
+
+showCoord :: Coord.Coord -> String
+showCoord coord =
+  "(" ++
+  maybe "?" show (Coord.lat coord) ++
+  "°, " ++ maybe "?" show (Coord.lon coord) ++ "°)"
+
+showWeather :: [Weather.Weather] -> String
+showWeather w = intercalate "," $ Weather.main <$> w
+
+showHumidity :: Main.Main -> String
+showHumidity m = "H " ++ show hm ++ " %"
+  where
+    hm :: Int
+    hm = round . Main.humidity $ m
+
+-- https://en.wikipedia.org/wiki/Millimeter_of_mercury
+showPressure :: Main.Main -> String
+showPressure m = "P " ++ show p ++ " mmHg"
+  where
+    hPa2mmHg hpa = hpa * 0.750061561303
+    p :: Int
+    p = round . hPa2mmHg . Main.pressure $ m
+
+-- https://stackoverflow.com/q/7490660/933161
+showWind :: Wind.Wind -> String
+showWind w = dir ++ " " ++ show speed ++ " m/s"
+  where
+    speed :: Int
+    speed = round . Wind.speed $ w
+    deg = Wind.deg w
+    --     [ "N", "NE", "E", "SE", "S", "SW", "W", "NW" ]
+    dirs = ["↓", "↙", "←", "↖", "↑", "↗", "→", "↘"]
+    l = length dirs
+    sector = round $ (deg * fromIntegral l) / 360.0
+    dir = dirs !! (sector `rem` l)
+
+showTemp :: Main.Main -> String
+showTemp m = "T " ++ temp ++ " °C"
+  where
+    k2c k = k - 273.15 -- Kelvin to Celsius
+    tmax :: Int
+    tmin :: Int
+    tmax = round . k2c . Main.temp_max $ m
+    tmin = round . k2c . Main.temp_min $ m
+    show' t =
+      if t > 0
+        then "+" ++ show t
+        else show t
+    temp =
+      if tmax /= tmin
+        then show' tmin ++ ".." ++ show' tmax
+        else show' tmin
diff --git a/lib/Web/OpenWeatherMap/API.hs b/lib/Web/OpenWeatherMap/API.hs
--- a/lib/Web/OpenWeatherMap/API.hs
+++ b/lib/Web/OpenWeatherMap/API.hs
@@ -6,33 +6,29 @@
 {-# LANGUAGE TypeOperators #-}
 
 module Web.OpenWeatherMap.API
-  ( weatherByName
-  , weatherByCoord
+  ( currentWeather
+  , forecastWeather
   ) where
 
 import Data.Proxy (Proxy(..))
 
-import Servant.API ((:<|>)(..), (:>), Get, JSON, QueryParam)
+import Servant.API ((:<|>)(..), (:>), Get, JSON, QueryParam', Required, Strict)
 import Servant.Client (ClientM, client)
 
 import Web.OpenWeatherMap.Types.CurrentWeather (CurrentWeather)
+import Web.OpenWeatherMap.Types.ForecastWeather (ForecastWeather)
+import Web.OpenWeatherMap.Types.Location (Location)
 
-type GetCurrentWeather = AppId :> Get '[ JSON] CurrentWeather
+type QueryParam = QueryParam' '[ Required, Strict]
 
-type AppId = QueryParam "appid" String
+type Current
+   = "weather" :> QueryParam "appid" String :> Location :> Get '[ JSON] CurrentWeather
 
-type API
-   = "weather" :> QueryParam "q" String :> GetCurrentWeather :<|> "weather" :> QueryParam "lat" Double :> QueryParam "lon" Double :> GetCurrentWeather
+type Forecast
+   = "forecast" :> QueryParam "appid" String :> Location :> Get '[ JSON] ForecastWeather
 
--- | Request current weather in the city.
-weatherByName ::
-     Maybe String -- ^ City name, e. g. \"Moscow\" or \"Moscow,ru\".
-  -> Maybe String -- ^ API key.
-  -> ClientM CurrentWeather
--- | Request current weather at the geographic coordinates (in decimal degrees).
-weatherByCoord ::
-     Maybe Double -- ^ Latitude, e. g. 55.7522200 for Moscow.
-  -> Maybe Double -- ^ Longitude, e. g. 37.6155600 for Moscow.
-  -> Maybe String -- ^ API key.
-  -> ClientM CurrentWeather
-weatherByName :<|> weatherByCoord = client (Proxy :: Proxy API)
+type API = Current :<|> Forecast
+
+forecastWeather :: String -> Location -> ClientM ForecastWeather
+currentWeather :: String -> Location -> ClientM CurrentWeather
+(currentWeather :<|> forecastWeather) = client (Proxy :: Proxy API)
diff --git a/lib/Web/OpenWeatherMap/Client.hs b/lib/Web/OpenWeatherMap/Client.hs
--- a/lib/Web/OpenWeatherMap/Client.hs
+++ b/lib/Web/OpenWeatherMap/Client.hs
@@ -2,8 +2,8 @@
 High-level client functions perfoming requests to OpenWeatherMap API.
 -}
 module Web.OpenWeatherMap.Client
-  ( Location(..)
-  , getWeather
+  ( getWeather
+  , getForecast
   ) where
 
 import Network.HTTP.Client (defaultManagerSettings, newManager)
@@ -11,7 +11,6 @@
   ( BaseUrl(BaseUrl)
   , ClientEnv
   , ClientError
-  , ClientM
   , Scheme(Http)
   , mkClientEnv
   , runClientM
@@ -19,12 +18,8 @@
 
 import qualified Web.OpenWeatherMap.API as API
 import Web.OpenWeatherMap.Types.CurrentWeather (CurrentWeather)
-
--- | Various way to specify location.
-data Location
-  = Name String -- ^ City name.
-  | Coord Double
-          Double -- ^ Geographic coordinates: latitude and longitude.
+import Web.OpenWeatherMap.Types.ForecastWeather (ForecastWeather)
+import Web.OpenWeatherMap.Types.Location (Location)
 
 -- | Make a request to OpenWeatherMap API
 --   and return current weather in given location.
@@ -32,14 +27,16 @@
      String -- ^ API key.
   -> Location
   -> IO (Either ClientError CurrentWeather)
-getWeather appid loc = defaultEnv >>= runClientM (api loc appid)
+getWeather appid loc = defaultEnv >>= runClientM (API.currentWeather appid loc)
 
-api ::
-     Location
-  -> String -- ^ API key.
-  -> ClientM CurrentWeather
-api (Name city) = API.weatherByName (Just city) . Just
-api (Coord lat lon) = API.weatherByCoord (Just lat) (Just lon) . Just
+-- | Make a request to OpenWeatherMap API
+--   and return forecast weather in given location.
+getForecast ::
+     String -- ^ API key.
+  -> Location
+  -> IO (Either ClientError ForecastWeather)
+getForecast appid loc =
+  defaultEnv >>= runClientM (API.forecastWeather appid loc)
 
 defaultEnv :: IO ClientEnv
 defaultEnv = do
diff --git a/lib/Web/OpenWeatherMap/Types/City.hs b/lib/Web/OpenWeatherMap/Types/City.hs
new file mode 100644
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/City.hs
@@ -0,0 +1,21 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.City
+  ( City(..)
+  ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.Coord (Coord)
+
+data City = City
+  { name :: String
+  , country :: Maybe String
+  , coord :: Coord
+  , timezone :: Int
+  , sunset :: Int
+  , sunrise :: Int
+  } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/Coord.hs b/lib/Web/OpenWeatherMap/Types/Coord.hs
--- a/lib/Web/OpenWeatherMap/Types/Coord.hs
+++ b/lib/Web/OpenWeatherMap/Types/Coord.hs
@@ -10,6 +10,6 @@
 import Data.Aeson (FromJSON)
 
 data Coord = Coord
-  { lon :: Double
-  , lat :: Double
+  { lon :: Maybe Double
+  , lat :: Maybe Double
   } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/Forecast.hs b/lib/Web/OpenWeatherMap/Types/Forecast.hs
new file mode 100644
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/Forecast.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.Forecast
+  ( Forecast(..)
+  ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.Clouds (Clouds)
+import Web.OpenWeatherMap.Types.Main (Main)
+import Web.OpenWeatherMap.Types.Weather (Weather)
+import Web.OpenWeatherMap.Types.Wind (Wind)
+
+data Forecast = Forecast
+  { dt :: Int
+  , clouds :: Clouds
+  , main :: Main
+  , weather :: [Weather]
+  , wind :: Wind
+  } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs b/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs
new file mode 100644
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/ForecastWeather.hs
@@ -0,0 +1,20 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric #-}
+
+module Web.OpenWeatherMap.Types.ForecastWeather
+  ( ForecastWeather(..)
+  ) where
+
+import GHC.Generics (Generic)
+
+import Data.Aeson (FromJSON)
+
+import Web.OpenWeatherMap.Types.City (City)
+import Web.OpenWeatherMap.Types.Forecast (Forecast)
+
+-- | Response to requests for forecast weather.
+-- Refer to <https://openweathermap.org/forecast5>.
+data ForecastWeather = ForecastWeather
+  { list :: [Forecast]
+  , city :: City
+  } deriving (Show, Generic, FromJSON)
diff --git a/lib/Web/OpenWeatherMap/Types/Location.hs b/lib/Web/OpenWeatherMap/Types/Location.hs
new file mode 100644
--- /dev/null
+++ b/lib/Web/OpenWeatherMap/Types/Location.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+module Web.OpenWeatherMap.Types.Location
+  ( Location(..)
+  ) where
+
+import Data.Proxy (Proxy(..))
+
+import Servant.API ((:>))
+import Servant.Client (Client, HasClient, clientWithRoute, hoistClientMonad)
+import Servant.Client.Core.Request (appendToQueryString)
+import Web.HttpApiData (toQueryParam)
+
+-- | Various way to specify location.
+data Location
+  = Name String -- ^ City name.
+  | Coord Double Double -- ^ Geographic coordinates: latitude and longitude.
+
+instance HasClient m api => HasClient m (Location :> api) where
+  type Client m (Location :> api) = Location -> Client m api
+  clientWithRoute pm Proxy req loc =
+    clientWithRoute pm (Proxy :: Proxy api) (addParams loc req)
+    where
+      addParams (Name q) = appendToQueryString "q" (Just $ toQueryParam q)
+      addParams (Coord lat lon) =
+        appendToQueryString "lat" (Just $ toQueryParam lat) .
+        appendToQueryString "lon" (Just $ toQueryParam lon)
+  hoistClientMonad pm _ f cl =
+    \a -> hoistClientMonad pm (Proxy :: Proxy api) f (cl a)
diff --git a/openweathermap.cabal b/openweathermap.cabal
--- a/openweathermap.cabal
+++ b/openweathermap.cabal
@@ -1,5 +1,5 @@
 name: openweathermap
-version: 0.1.0
+version: 0.2.0
 synopsis: Access data at OpenWeatherMap
 description: Client library and command-line utility to access
   OpenWeatherMap https://openweathermap.org
@@ -28,15 +28,21 @@
   build-depends:
       base >= 4.9 && < 5
     , aeson
+    , http-api-data
     , http-client
     , servant
     , servant-client >= 0.16
+    , servant-client-core
   exposed-modules:
      Web.OpenWeatherMap.API
      Web.OpenWeatherMap.Client
+     Web.OpenWeatherMap.Types.City
      Web.OpenWeatherMap.Types.Clouds
      Web.OpenWeatherMap.Types.Coord
      Web.OpenWeatherMap.Types.CurrentWeather
+     Web.OpenWeatherMap.Types.Forecast
+     Web.OpenWeatherMap.Types.ForecastWeather
+     Web.OpenWeatherMap.Types.Location
      Web.OpenWeatherMap.Types.Main
      Web.OpenWeatherMap.Types.Sys
      Web.OpenWeatherMap.Types.Weather
@@ -47,12 +53,14 @@
   ghc-options: -Wall -static
   hs-source-dirs: cmd
   main-is: Main.hs
+  other-modules: Print
   if flag(cmd)
     build-depends:
         base >= 4.9 && < 5
       , directory
       , openweathermap
       , optparse-applicative >= 0.13.0.0
+      , time
       , xdg-basedir
   else
     buildable: False
