casa-reoc-0.1.0.0: src/ReOC/Data/CRINominee.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
-- The checks of inheritance (inheritCRINominee') have a constraint that their body does not use, by design.
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
-- | The data type @CRINominee'@: who is nominated as chief RePL instructor (CASA Form 101-02, question 13): the CEO, the chief remote pilot, the maintenance controller, or another person.
module ReOC.Data.CRINominee (
CRINominee' (..),
CRINominee'Like (..),
lawNamesCRINominee',
CRINominee,
UnfilledCRINominee,
InheritCRINominee',
inheritCRINominee',
) where
import Control.Lens (Choice, Optic, prism, prism', review)
import Data.Functor.Const (Const)
import ReOC.Data.Nominee (Nominee, UnfilledNominee)
import ReOC.Name.CriIsCEO (CriIsCEOLike (..))
import ReOC.Name.CriIsCRP (CriIsCRPLike (..))
import ReOC.Name.CriIsMC (CriIsMCLike (..))
import ReOC.Name.CriNominated (CriNominatedLike (..))
-- | Who is nominated as chief RePL instructor (CASA Form 101-02, question 13): the CEO, the chief remote pilot, the maintenance controller, or another person. Its valid form is @CRINominee@, and its unfilled form @UnfilledCRINominee@.
data CRINominee' a1
= CRIIsCEO
| CRIIsCRP
| CRIIsMC
| CRINominated a1
deriving (Eq, Ord, Show)
-- | The name of the data type @CRINominee'@.
class CRINominee'Like p f x x' a1 a1' | x -> a1 where
criNominee' ::
Optic p f x x' (CRINominee' a1) (CRINominee' a1')
-- | Identity
instance (x' ~ CRINominee' a1') => CRINominee'Like p f (CRINominee' a1) x' a1 a1' where
criNominee' = id
-- | Prism
instance (Choice p, Applicative f, x' ~ CRINominee' a1) => CriIsCEOLike p f (CRINominee' a1) x' where
criIsCEO = prism' (\() -> CRIIsCEO) (\case CRIIsCEO -> Just (); CRIIsCRP -> Nothing; CRIIsMC -> Nothing; CRINominated _ -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ CRINominee' a1) => CriIsCRPLike p f (CRINominee' a1) x' where
criIsCRP = prism' (\() -> CRIIsCRP) (\case CRIIsCEO -> Nothing; CRIIsCRP -> Just (); CRIIsMC -> Nothing; CRINominated _ -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ CRINominee' a1) => CriIsMCLike p f (CRINominee' a1) x' where
criIsMC = prism' (\() -> CRIIsMC) (\case CRIIsCEO -> Nothing; CRIIsCRP -> Nothing; CRIIsMC -> Just (); CRINominated _ -> Nothing)
-- | Prism
instance (Choice p, Applicative f, x' ~ CRINominee' a1') => CriNominatedLike p f (CRINominee' a1) x' a1 a1' where
criNominated = prism CRINominated (\case CRIIsCEO -> Left CRIIsCEO; CRIIsCRP -> Left CRIIsCRP; CRIIsMC -> Left CRIIsMC; CRINominated x -> Right x)
{- | Rebuilds a value from the name of each field or constructor.
Laws:
> lawNamesCRINominee' == id
-}
lawNamesCRINominee' :: CRINominee' a1 -> CRINominee' a1
lawNamesCRINominee' = \case
CRIIsCEO -> review criIsCEO ()
CRIIsCRP -> review criIsCRP ()
CRIIsMC -> review criIsMC ()
CRINominated x -> review criNominated x
-- | A valid @CRINominee'@.
type CRINominee = CRINominee' Nominee
-- | An unfilled @CRINominee'@: each field holds what has been entered, if anything, to be checked by @fillCRINominee@.
type UnfilledCRINominee = CRINominee' UnfilledNominee
-- | The classes that a data type holding @CRINominee'@ in one field, or in one or more constructors, inherits.
type InheritCRINominee' s a1 =
( CRINominee'Like (->) (Const ()) s s a1 a1
, CriIsCEOLike (->) (Const ()) s s
, CriIsCRPLike (->) (Const ()) s s
, CriIsMCLike (->) (Const ()) s s
, CriNominatedLike (->) (Const ()) s s a1 a1
)
-- | Checks that a data type inherits every class of @InheritCRINominee'@.
inheritCRINominee' :: (InheritCRINominee' s a1) => proxy s -> ()
inheritCRINominee' _ = ()