repos / handle-examples.hs.git


handle-examples.hs.git / row-handle / domain
Evgenii Akentev  ·  2023-04-01

WeatherProvider.hs

 1{-# LANGUAGE DataKinds #-}
 2{-# LANGUAGE OverloadedStrings #-}
 3{-# LANGUAGE TypeOperators #-}
 4{-# LANGUAGE TypeApplications #-}
 5
 6module WeatherProvider where
 7
 8import Data.Row
 9import HandleRow
10import qualified WindProvider
11import qualified TemperatureProvider
12import QueryTypes
13
14data WeatherData = WeatherData { temperature :: TemperatureProvider.Temperature, wind :: WindProvider.WindSpeed }
15
16-- We union the methods of providers and extend it with a common method.
17type Methods = ("getWeatherData" .== (Location -> Day -> IO WeatherData))
18  .+ WindProvider.Methods
19  .+ TemperatureProvider.Methods
20
21type Handle = HandleRow Methods
22
23getWeatherData :: Handle -> Location -> Day -> IO WeatherData
24getWeatherData = getMethod @"getWeatherData"
25
26getWindData :: Handle -> Location -> Day -> IO WindProvider.WindSpeed
27getWindData = getMethod @"getWindData"
28
29-- Some examples of what else is possible with row types.
30
31-- We can remove an item from the record
32type WindAndTemperatureMethods = Methods .- "getWeatherData"
33
34test1 :: Rec WindAndTemperatureMethods -> Rec (WindProvider.Methods .+ TemperatureProvider.Methods)
35test1 = id
36
37-- It's possible to override methods
38type MethodsWithUpdatedWeatherData = ("getWeatherData" .== (Location -> Day -> IO Int)) .// Methods
39
40test2 :: Rec MethodsWithUpdatedWeatherData -> Rec (("getWeatherData" .== (Location -> Day -> IO Int)) .+ WindProvider.Methods .+ TemperatureProvider.Methods)
41test2 = id
42
43-- And to remove them by taking a row difference
44type MethodsWithoutWeatherData = Methods .\\ ("getWeatherData" .== (Location -> Day -> IO WeatherData))
45
46test3 :: Rec MethodsWithoutWeatherData -> Rec WindAndTemperatureMethods
47test3 = id
48
49-- The minimum join of the two rows.
50type JoinedMethods = Methods .\/ Methods
51
52test4 :: Rec JoinedMethods -> Rec Methods
53test4 = id