casa-reoc-0.1.0.0: src/ReOC/Data/RadioQualification.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
-- The checks of inheritance (inheritRadioQualification) have a constraint that their body does not use, by design.
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
-- | The data type @RadioQualification@: the qualification of the chief remote pilot to use an aeronautical radio.
module ReOC.Data.RadioQualification (
RadioQualification (..),
RadioQualificationLike (..),
lawNamesRadioQualification,
InheritRadioQualification,
inheritRadioQualification,
) where
import Control.Lens (Choice, Optic, prism', review)
import Data.Functor.Const (Const)
import ReOC.Name.FlightCrewLicence (FlightCrewLicenceLike (..))
import ReOC.Name.NoRadioQualification (NoRadioQualificationLike (..))
import ReOC.Name.RadioOperatorCertificate (RadioOperatorCertificateLike (..))
-- | The qualification of the chief remote pilot to use an aeronautical radio.
data RadioQualification
= FlightCrewLicence
| RadioOperatorCertificate
| NoRadioQualification
deriving (Eq, Ord, Show)
-- | The name of the data type @RadioQualification@.
class RadioQualificationLike p f x x' where
radioQualification ::
Optic p f x x' RadioQualification RadioQualification
-- | Identity
instance (x' ~ RadioQualification) => RadioQualificationLike p f RadioQualification x' where
radioQualification = id
-- | Prism
instance (Choice p, Applicative f, x' ~ RadioQualification) => FlightCrewLicenceLike p f RadioQualification x' where
flightCrewLicence = prism' (\() -> FlightCrewLicence) (\case FlightCrewLicence -> Just (); RadioOperatorCertificate -> Nothing; NoRadioQualification -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ RadioQualification) => RadioOperatorCertificateLike p f RadioQualification x' where
radioOperatorCertificate = prism' (\() -> RadioOperatorCertificate) (\case FlightCrewLicence -> Nothing; RadioOperatorCertificate -> Just (); NoRadioQualification -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ RadioQualification) => NoRadioQualificationLike p f RadioQualification x' where
noRadioQualification = prism' (\() -> NoRadioQualification) (\case FlightCrewLicence -> Nothing; RadioOperatorCertificate -> Nothing; NoRadioQualification -> Just ())
{- | Rebuilds a value from the name of each field or constructor.
Laws:
> lawNamesRadioQualification == id
-}
lawNamesRadioQualification :: RadioQualification -> RadioQualification
lawNamesRadioQualification = \case
FlightCrewLicence -> review flightCrewLicence ()
RadioOperatorCertificate -> review radioOperatorCertificate ()
NoRadioQualification -> review noRadioQualification ()
-- | The classes that a data type holding @RadioQualification@ in one field, or in one or more constructors, inherits.
type InheritRadioQualification s =
( RadioQualificationLike (->) (Const ()) s s
, FlightCrewLicenceLike (->) (Const ()) s s
, RadioOperatorCertificateLike (->) (Const ()) s s
, NoRadioQualificationLike (->) (Const ()) s s
)
-- | Checks that a data type inherits every class of @InheritRadioQualification@.
inheritRadioQualification :: (InheritRadioQualification s) => proxy s -> ()
inheritRadioQualification _ = ()