packages feed

casa-reoc-0.1.0.0: src/ReOC/Data/OtherReOCRoles.hs

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
-- The checks of inheritance (inheritOtherReOCRoles') have a constraint that their body does not use, by design.
{-# OPTIONS_GHC -Wno-redundant-constraints #-}

-- | The data type @OtherReOCRoles'@: whether a person is also a chief remote pilot or chief RePL instructor for other ReOC holders (CASA Form 101-02, questions 11 and 18).
module ReOC.Data.OtherReOCRoles (
  OtherReOCRoles' (..),
  OtherReOCRoles'Like (..),
  lawNamesOtherReOCRoles',
  OtherReOCRoles,
  UnfilledOtherReOCRoles,
  InheritOtherReOCRoles',
  inheritOtherReOCRoles',
) where

import Control.Lens (Choice, Optic, prism, prism', review)
import Data.Functor.Const (Const)
import Data.Text (Text)
import ReOC.Name.NoOtherReOCRoles (NoOtherReOCRolesLike (..))
import ReOC.Name.OtherReOCRolesHeld (OtherReOCRolesHeldLike (..))
import ReOC.Primitive.FormText (FormLines)

-- | Whether a person is also a chief remote pilot or chief RePL instructor for other ReOC holders (CASA Form 101-02, questions 11 and 18). Its valid form is @OtherReOCRoles@, and its unfilled form @UnfilledOtherReOCRoles@.
data OtherReOCRoles' a1
  = NoOtherReOCRoles
  | OtherReOCRolesHeld a1
  deriving (Eq, Ord, Show)

-- | The name of the data type @OtherReOCRoles'@.
class OtherReOCRoles'Like p f x x' a1 a1' | x -> a1 where
  otherReOCRoles' ::
    Optic p f x x' (OtherReOCRoles' a1) (OtherReOCRoles' a1')

-- | Identity
instance (x' ~ OtherReOCRoles' a1') => OtherReOCRoles'Like p f (OtherReOCRoles' a1) x' a1 a1' where
  otherReOCRoles' = id

-- | Prism
instance (Choice p, Applicative f, x' ~ OtherReOCRoles' a1) => NoOtherReOCRolesLike p f (OtherReOCRoles' a1) x' where
  noOtherReOCRoles = prism' (\() -> NoOtherReOCRoles) (\case NoOtherReOCRoles -> Just (); OtherReOCRolesHeld _ -> Nothing)

-- | Prism
instance (Choice p, Applicative f, x' ~ OtherReOCRoles' a1') => OtherReOCRolesHeldLike p f (OtherReOCRoles' a1) x' a1 a1' where
  otherReOCRolesHeld = prism OtherReOCRolesHeld (\case NoOtherReOCRoles -> Left NoOtherReOCRoles; OtherReOCRolesHeld x -> Right x)

{- | Rebuilds a value from the name of each field or constructor.

Laws:

> lawNamesOtherReOCRoles' == id
-}
lawNamesOtherReOCRoles' :: OtherReOCRoles' a1 -> OtherReOCRoles' a1
lawNamesOtherReOCRoles' = \case
  NoOtherReOCRoles -> review noOtherReOCRoles ()
  OtherReOCRolesHeld x -> review otherReOCRolesHeld x

-- | A valid @OtherReOCRoles'@.
type OtherReOCRoles = OtherReOCRoles' (FormLines 5)

-- | An unfilled @OtherReOCRoles'@: each field holds what has been entered, if anything, to be checked by @fillOtherReOCRoles@.
type UnfilledOtherReOCRoles = OtherReOCRoles' (Maybe Text)

-- | The classes that a data type holding @OtherReOCRoles'@ in one field, or in one or more constructors, inherits.
type InheritOtherReOCRoles' s a1 =
  ( OtherReOCRoles'Like (->) (Const ()) s s a1 a1
  , NoOtherReOCRolesLike (->) (Const ()) s s
  , OtherReOCRolesHeldLike (->) (Const ()) s s a1 a1
  )

-- | Checks that a data type inherits every class of @InheritOtherReOCRoles'@.
inheritOtherReOCRoles' :: (InheritOtherReOCRoles' s a1) => proxy s -> ()
inheritOtherReOCRoles' _ = ()