-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathReservationDomain.hs
71 lines (60 loc) · 2.38 KB
/
ReservationDomain.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
module Domain.ReservationDomain
( Reservation (..),
ReservationMap,
usedCapacity,
availableSeats,
isReservationPossible,
addReservation,
cancelReservation,
)
where
import Data.Aeson.Types (FromJSON, ToJSON)
import Data.List (delete)
import qualified Data.Map.Strict as M
import Data.Time.Calendar
import GHC.Generics
import Numeric.Natural
{--
This module implements the business logic for seat reservations in a very small boutique restaurant.
The restaurant has only one table with 20 seats.
Each day the restaurants accepts only 20 seat reservations. (There is no limited time-slot for each guest.)
Please note: all functions in this module are pure and total.
This makes it easy to test them in isolation.
--}
-- | a data type representing a reservation
data Reservation = Reservation
{ -- | the date of the reservation
date :: Day,
-- | the name of the guest placing the reservation
name :: String,
-- | the email address of the guest
email :: String,
-- | how many seats are requested
quantity :: Natural
}
deriving (Eq, Generic, Show, ToJSON, FromJSON)
-- | a key value map holding a list of reservations for any given day
type ReservationMap = M.Map Day [Reservation]
-- | computes the number of reserved seats for a list of reservations
usedCapacity :: [Reservation] -> Natural
usedCapacity [] = 0
usedCapacity (Reservation _ _ _ requested : rest) = requested + usedCapacity rest
-- | check whether it is possible to add a reservation to the table.
-- | Return True if successful, else return False
isReservationPossible :: Reservation -> [Reservation] -> Natural -> Bool
isReservationPossible (Reservation _ _ _ requestedSeats) reservationsOnDay maxCapacity =
availableSeats maxCapacity reservationsOnDay >= requestedSeats
-- | computes the number of available seats from a maximum capacity and a list of reservations.
availableSeats :: Natural -> [Reservation] -> Natural
availableSeats maxCapacity reservations =
if maxCapacity < usedCapacity reservations
then 0
else maxCapacity - usedCapacity reservations
-- | add a reservation to
addReservation :: Reservation -> [Reservation] -> [Reservation]
addReservation r rs = r : rs
-- | cancel a reservation for a given list of reservations.
cancelReservation :: Reservation -> [Reservation] -> [Reservation]
cancelReservation = delete