casa-reoc-0.1.0.0: src/ReOC/Data/BackupInterval.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
-- The checks of inheritance (inheritBackupInterval) have a constraint that their body does not use, by design.
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
-- | The data type @BackupInterval@: the longest interval between backups of the operator’s records.
module ReOC.Data.BackupInterval (
BackupInterval (..),
BackupIntervalLike (..),
lawNamesBackupInterval,
InheritBackupInterval,
inheritBackupInterval,
) where
import Control.Lens (Choice, Optic, prism', review)
import Data.Functor.Const (Const)
import ReOC.Name.Daily (DailyLike (..))
import ReOC.Name.Monthly (MonthlyLike (..))
import ReOC.Name.Weekly (WeeklyLike (..))
-- | The longest interval between backups of the operator’s records.
data BackupInterval
= Daily
| Weekly
| Monthly
deriving (Eq, Ord, Show)
-- | The name of the data type @BackupInterval@.
class BackupIntervalLike p f x x' where
backupInterval ::
Optic p f x x' BackupInterval BackupInterval
-- | Identity
instance (x' ~ BackupInterval) => BackupIntervalLike p f BackupInterval x' where
backupInterval = id
-- | Prism
instance (Choice p, Applicative f, x' ~ BackupInterval) => DailyLike p f BackupInterval x' where
daily = prism' (\() -> Daily) (\case Daily -> Just (); Weekly -> Nothing; Monthly -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ BackupInterval) => WeeklyLike p f BackupInterval x' where
weekly = prism' (\() -> Weekly) (\case Daily -> Nothing; Weekly -> Just (); Monthly -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ BackupInterval) => MonthlyLike p f BackupInterval x' where
monthly = prism' (\() -> Monthly) (\case Daily -> Nothing; Weekly -> Nothing; Monthly -> Just ())
{- | Rebuilds a value from the name of each field or constructor.
Laws:
> lawNamesBackupInterval == id
-}
lawNamesBackupInterval :: BackupInterval -> BackupInterval
lawNamesBackupInterval = \case
Daily -> review daily ()
Weekly -> review weekly ()
Monthly -> review monthly ()
-- | The classes that a data type holding @BackupInterval@ in one field, or in one or more constructors, inherits.
type InheritBackupInterval s =
( BackupIntervalLike (->) (Const ()) s s
, DailyLike (->) (Const ()) s s
, WeeklyLike (->) (Const ()) s s
, MonthlyLike (->) (Const ()) s s
)
-- | Checks that a data type inherits every class of @InheritBackupInterval@.
inheritBackupInterval :: (InheritBackupInterval s) => proxy s -> ()
inheritBackupInterval _ = ()