filepather-0.8.0.0: src/System/FilePather/RepeatsStep.hs
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wall #-}
{- | A step that is already in its trail.
A 'RepeatsStep' is a product: its fields are named 'step' and 'trail'. It
holds a 'Step' and a 'Trail', so it inherits their names.
-}
module System.FilePather.RepeatsStep (
-- * Type
RepeatsStep (..),
-- * Optics
RepeatsStepLike (..),
lawNamesRepeatsStep,
InheritRepeatsStep,
inheritRepeatsStep,
inheritsRepeatsStep,
) where
import Control.DeepSeq (NFData)
import Control.Lens (Optic, cloneLens, view)
import Data.Data (Data)
import Data.Functor.Const (Const)
import Data.Proxy (Proxy (..))
import GHC.Generics (Generic)
import System.FilePather.Name.StepInput (StepInputLike (..))
import System.FilePather.Name.StepName (StepNameLike (..))
import System.FilePather.Name.Steps (StepsLike (..))
import System.FilePather.Step (Step, StepLike (..), inheritStep)
import System.FilePather.Trail (Trail, TrailLike (..), inheritTrail)
{- | A step is already in the trail of its input file: the step ('step'), and
the trail ('trail').
@since 0.8.0.0
-}
data RepeatsStep
= RepeatsStep Step Trail
deriving stock (Eq, Ord, Show, Generic, Data)
deriving anyclass (NFData)
{- | The class of 'RepeatsStep'.
@since 0.8.0.0
-}
class RepeatsStepLike p f x x' where
repeatsStep ::
Optic p f x x' RepeatsStep RepeatsStep
{- | Identity
@since 0.8.0.0
-}
instance (x' ~ RepeatsStep) => RepeatsStepLike p f RepeatsStep x' where
repeatsStep =
id
{-# INLINE repeatsStep #-}
{- | Lens: 'step' is the default name of the field of type 'Step'.
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ RepeatsStep) => StepLike p f RepeatsStep x' where
step f (RepeatsStep s t) =
fmap (`RepeatsStep` t) (f s)
{-# INLINE step #-}
{- | Lens: 'trail' is the default name of the field of type 'Trail'.
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ RepeatsStep) => TrailLike p f RepeatsStep x' where
trail f (RepeatsStep s t) =
fmap (RepeatsStep s) (f t)
{-# INLINE trail #-}
{- | Lens: through 'step', a lens, then 'Step''s 'stepName', a lens.
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ RepeatsStep) => StepNameLike p f RepeatsStep x' where
stepName =
step . stepName
{-# INLINE stepName #-}
{- | Lens: through 'step', a lens, then 'Step''s 'stepInput', a lens.
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ RepeatsStep) => StepInputLike p f RepeatsStep x' where
stepInput =
step . stepInput
{-# INLINE stepInput #-}
{- | Lens: through 'trail', a lens, then 'Trail''s 'steps', a lens.
@since 0.8.0.0
-}
instance (p ~ (->), Functor f, x' ~ RepeatsStep) => StepsLike p f RepeatsStep x' where
steps =
trail . steps
{-# INLINE steps #-}
{- | Rebuild a value using only the name of each field.
Laws:
> lawNamesRepeatsStep == id
@since 0.8.0.0
-}
lawNamesRepeatsStep :: RepeatsStep -> RepeatsStep
lawNamesRepeatsStep s =
RepeatsStep (view (cloneLens step) s) (view (cloneLens trail) s)
{- | The classes that a data type holding 'RepeatsStep' inherits.
@since 0.8.0.0
-}
type InheritRepeatsStep s =
( RepeatsStepLike (->) (Const ()) s s
, StepLike (->) (Const ()) s s
, TrailLike (->) (Const ()) s s
, StepNameLike (->) (Const ()) s s
, StepInputLike (->) (Const ()) s s
, StepsLike (->) (Const ()) s s
)
{- | Check, where it is applied, that @s@ inherits every name of
'RepeatsStep'.
@since 0.8.0.0
-}
inheritRepeatsStep :: (InheritRepeatsStep s) => proxy s -> ()
inheritRepeatsStep _ =
()
{- | 'RepeatsStep' inherits every name of 'Step' and of 'Trail'.
@since 0.8.0.0
-}
inheritsRepeatsStep :: [()]
inheritsRepeatsStep =
let p = Proxy :: Proxy RepeatsStep
in [inheritStep p, inheritTrail p]