packages feed

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

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

-- | The data type @FirstIssue'@: the first entry in the amendment record of the operations manual: its version and date, and the effective date, parts and details.
module ReOC.Data.FirstIssue (
  FirstIssue' (..),
  FirstIssue'Like (..),
  lawNamesFirstIssue',
  FirstIssue,
  UnfilledFirstIssue,
  mkUnfilledFirstIssue,
  InheritFirstIssue',
  inheritFirstIssue',
) where

import Control.Lens (Optic, cloneLens, view)
import Data.Functor.Const (Const)
import Data.Text (Text)
import Data.Time.Calendar.Month (Month)
import ReOC.Data.Version (UnfilledVersion, Version, mkUnfilledVersion)
import ReOC.Name.Details (DetailsLike (..))
import ReOC.Name.Effective (EffectiveLike (..))
import ReOC.Name.IssueDate (IssueDateLike (..))
import ReOC.Name.Parts (PartsLike (..))
import ReOC.Name.Version (VersionLike (..))
import ReOC.Primitive.Text1 (Text1)

-- | The first entry in the amendment record of the operations manual: its version and date, and the effective date, parts and details. Its valid form is @FirstIssue@, and its unfilled form @UnfilledFirstIssue@.
data FirstIssue' a1 a2 a3 a4 a5 = FirstIssue' a1 a2 a3 a4 a5
  deriving (Eq, Ord, Show)

-- | The name of the data type @FirstIssue'@.
class FirstIssue'Like p f x x' a1 a1' a2 a2' a3 a3' a4 a4' a5 a5' | x -> a1 a2 a3 a4 a5 where
  firstIssue' ::
    Optic p f x x' (FirstIssue' a1 a2 a3 a4 a5) (FirstIssue' a1' a2' a3' a4' a5')

-- | Identity
instance (x' ~ FirstIssue' a1' a2' a3' a4' a5') => FirstIssue'Like p f (FirstIssue' a1 a2 a3 a4 a5) x' a1 a1' a2 a2' a3 a3' a4 a4' a5 a5' where
  firstIssue' = id

-- | Lens
instance (p ~ (->), Functor f, x' ~ FirstIssue' a1' a2 a3 a4 a5) => VersionLike p f (FirstIssue' a1 a2 a3 a4 a5) x' a1 a1' where
  version f (FirstIssue' x1 x2 x3 x4 x5) = fmap (\x1' -> FirstIssue' x1' x2 x3 x4 x5) (f x1)

-- | Lens
instance (p ~ (->), Functor f, x' ~ FirstIssue' a1 a2' a3 a4 a5) => IssueDateLike p f (FirstIssue' a1 a2 a3 a4 a5) x' a2 a2' where
  issueDate f (FirstIssue' x1 x2 x3 x4 x5) = fmap (\x2' -> FirstIssue' x1 x2' x3 x4 x5) (f x2)

-- | Lens
instance (p ~ (->), Functor f, x' ~ FirstIssue' a1 a2 a3' a4 a5) => EffectiveLike p f (FirstIssue' a1 a2 a3 a4 a5) x' a3 a3' where
  effective f (FirstIssue' x1 x2 x3 x4 x5) = fmap (\x3' -> FirstIssue' x1 x2 x3' x4 x5) (f x3)

-- | Lens
instance (p ~ (->), Functor f, x' ~ FirstIssue' a1 a2 a3 a4' a5) => PartsLike p f (FirstIssue' a1 a2 a3 a4 a5) x' a4 a4' where
  parts f (FirstIssue' x1 x2 x3 x4 x5) = fmap (\x4' -> FirstIssue' x1 x2 x3 x4' x5) (f x4)

-- | Lens
instance (p ~ (->), Functor f, x' ~ FirstIssue' a1 a2 a3 a4 a5') => DetailsLike p f (FirstIssue' a1 a2 a3 a4 a5) x' a5 a5' where
  details f (FirstIssue' x1 x2 x3 x4 x5) = fmap (FirstIssue' x1 x2 x3 x4) (f x5)

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

Laws:

> lawNamesFirstIssue' == id
-}
lawNamesFirstIssue' :: FirstIssue' a1 a2 a3 a4 a5 -> FirstIssue' a1 a2 a3 a4 a5
lawNamesFirstIssue' s =
  FirstIssue'
    (view (cloneLens version) s)
    (view (cloneLens issueDate) s)
    (view (cloneLens effective) s)
    (view (cloneLens parts) s)
    (view (cloneLens details) s)

-- | A valid @FirstIssue'@.
type FirstIssue = FirstIssue' Version Month Text1 Text1 Text1

-- | An unfilled @FirstIssue'@: each field holds what has been entered, if anything, to be checked by @fillFirstIssue@.
type UnfilledFirstIssue = FirstIssue' UnfilledVersion (Maybe Month) (Maybe Text) (Maybe Text) (Maybe Text)

-- | An unfilled @FirstIssue'@ with nothing entered.
mkUnfilledFirstIssue :: UnfilledFirstIssue
mkUnfilledFirstIssue =
  FirstIssue'
    mkUnfilledVersion
    Nothing
    Nothing
    Nothing
    Nothing

-- | The classes that a data type holding @FirstIssue'@ in one field, or in one or more constructors, inherits.
type InheritFirstIssue' s a1 a2 a3 a4 a5 =
  ( FirstIssue'Like (->) (Const ()) s s a1 a1 a2 a2 a3 a3 a4 a4 a5 a5
  , VersionLike (->) (Const ()) s s a1 a1
  , IssueDateLike (->) (Const ()) s s a2 a2
  , EffectiveLike (->) (Const ()) s s a3 a3
  , PartsLike (->) (Const ()) s s a4 a4
  , DetailsLike (->) (Const ()) s s a5 a5
  )

-- | Checks that a data type inherits every class of @InheritFirstIssue'@.
inheritFirstIssue' :: (InheritFirstIssue' s a1 a2 a3 a4 a5) => proxy s -> ()
inheritFirstIssue' _ = ()