-- | Functions for modifying requests and actions

module SupplyChain.Alter
  (
    {- * General -} job, vendor, request, perform,
    {- * Simplified -} job', vendor', request', perform',
  )
  where

import SupplyChain.Core.Effect (Effect)
import SupplyChain.Core.Job (Job)
import SupplyChain.Core.Vendor (Vendor (..))

import qualified SupplyChain.Core.Effect as Effect
import qualified SupplyChain.Core.Job as Job
import qualified SupplyChain.Core.Vendor as Vendor

import Data.Function ((.))

job :: (forall x. Effect up action x -> Job up' action' x)
    -- ^ Transformation applied to each effect that the job evokes
    -> Job up action product -> Job up' action' product
job :: forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) product.
(forall x. Effect up action x -> Job up' action' x)
-> Job up action product -> Job up' action' product
job = forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) product.
(forall x. Effect up action x -> Job up' action' x)
-> Job up action product -> Job up' action' product
Job.alter

job' :: (forall x. Effect up action x -> Effect up' action' x)
    -- ^ Transformation applied to each effect that the job evokes
    -> Job up action product -> Job up' action' product
job' :: forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) product.
(forall x. Effect up action x -> Effect up' action' x)
-> Job up action product -> Job up' action' product
job' forall x. Effect up action x -> Effect up' action' x
f = forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) product.
(forall x. Effect up action x -> Job up' action' x)
-> Job up action product -> Job up' action' product
Job.alter (forall (up :: * -> *) (action :: * -> *) product.
Effect up action product -> Job up action product
Job.effect forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall x. Effect up action x -> Effect up' action' x
f)

vendor :: (forall x. Effect up action x -> Job up' action' x)
    -- ^ Transformation applied to each effect that the vendor evokes
    -> Vendor up down action -> Vendor up' down action'
vendor :: forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) (down :: * -> *).
(forall x. Effect up action x -> Job up' action' x)
-> Vendor up down action -> Vendor up' down action'
vendor = forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) (down :: * -> *).
(forall x. Effect up action x -> Job up' action' x)
-> Vendor up down action -> Vendor up' down action'
Vendor.alter

vendor' :: (forall x. Effect up action x -> Effect up' action' x)
    -- ^ Transformation applied to each effect that the vendor evokes
    -> Vendor up down action -> Vendor up' down action'
vendor' :: forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) (down :: * -> *).
(forall x. Effect up action x -> Effect up' action' x)
-> Vendor up down action -> Vendor up' down action'
vendor' forall x. Effect up action x -> Effect up' action' x
f = forall (up :: * -> *) (action :: * -> *) (up' :: * -> *)
       (action' :: * -> *) (down :: * -> *).
(forall x. Effect up action x -> Job up' action' x)
-> Vendor up down action -> Vendor up' down action'
Vendor.alter (forall (up :: * -> *) (action :: * -> *) product.
Effect up action product -> Job up action product
Job.effect forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall x. Effect up action x -> Effect up' action' x
f)

request :: (up product -> Effect up' action product)
    -- ^ Transformation applied if the effect is a request
    -> Effect up action product -> Effect up' action product
request :: forall {k} (up :: k -> *) (product :: k) (up' :: k -> *)
       (action :: k -> *).
(up product -> Effect up' action product)
-> Effect up action product -> Effect up' action product
request = forall {k} (up :: k -> *) (product :: k) (up' :: k -> *)
       (action :: k -> *).
(up product -> Effect up' action product)
-> Effect up action product -> Effect up' action product
Effect.alterRequest

request' :: (up product -> up' product)
    -- ^ Transformation applied if the effect is a request
    -> Effect up action product -> Effect up' action product
request' :: forall {k} (up :: k -> *) (product :: k) (up' :: k -> *)
       (action :: k -> *).
(up product -> up' product)
-> Effect up action product -> Effect up' action product
request' up product -> up' product
f = forall {k} (up :: k -> *) (product :: k) (up' :: k -> *)
       (action :: k -> *).
(up product -> Effect up' action product)
-> Effect up action product -> Effect up' action product
Effect.alterRequest (forall {k} (up :: k -> *) (action :: k -> *) (product :: k).
up product -> Effect up action product
Effect.Request forall b c a. (b -> c) -> (a -> b) -> a -> c
. up product -> up' product
f)

perform :: (action product -> Effect up action' product)
    -- ^ Transformation applied if the effect is an action
    -> Effect up action product -> Effect up action' product
perform :: forall {k} (action :: k -> *) (product :: k) (up :: k -> *)
       (action' :: k -> *).
(action product -> Effect up action' product)
-> Effect up action product -> Effect up action' product
perform = forall {k} (action :: k -> *) (product :: k) (up :: k -> *)
       (action' :: k -> *).
(action product -> Effect up action' product)
-> Effect up action product -> Effect up action' product
Effect.alterPerform

perform' :: (action product -> action' product)
    -- ^ Transformation applied if the effect is an action
    -> Effect up action product -> Effect up action' product
perform' :: forall {k} (action :: k -> *) (product :: k) (action' :: k -> *)
       (up :: k -> *).
(action product -> action' product)
-> Effect up action product -> Effect up action' product
perform' action product -> action' product
f = forall {k} (action :: k -> *) (product :: k) (up :: k -> *)
       (action' :: k -> *).
(action product -> Effect up action' product)
-> Effect up action product -> Effect up action' product
Effect.alterPerform (forall {k} (up :: k -> *) (action :: k -> *) (product :: k).
action product -> Effect up action product
Effect.Perform forall b c a. (b -> c) -> (a -> b) -> a -> c
. action product -> action' product
f)