-- editorconfig-checker-disable-file
{-# LANGUAGE FlexibleContexts #-}
-- | PlutusIR versions of the functions in PlutusCore.Normalize
module PlutusIR.Normalize
    ( Export.normalizeType
    , normalizeTypesIn
    , normalizeTypesInProgram
    ) where

import PlutusCore.Core as PLC (Normalized (..))
import PlutusCore.Name.Unique
import PlutusCore.Normalize as Export (normalizeType)
import PlutusCore.Normalize.Internal hiding (normalizeTypesInM)
import PlutusCore.Quote
import PlutusCore.Rename (rename)
import PlutusIR
import PlutusIR.Transform.Rename ()

import Control.Lens
import Control.Monad ((>=>))
import Universe (HasUniApply)

-- | Normalize every 'Type' in a 'Term'.
normalizeTypesIn
    :: (HasUnique tyname TypeUnique, HasUnique name TermUnique, MonadQuote m, HasUniApply uni)
    => Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
normalizeTypesIn :: forall tyname name (m :: * -> *) (uni :: * -> *) fun ann.
(HasUnique tyname TypeUnique, HasUnique name TermUnique,
 MonadQuote m, HasUniApply uni) =>
Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
normalizeTypesIn = Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
forall a (m :: * -> *). (Rename a, MonadQuote m) => a -> m a
forall (m :: * -> *).
MonadQuote m =>
Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
rename (Term tyname name uni fun ann -> m (Term tyname name uni fun ann))
-> (Term tyname name uni fun ann
    -> m (Term tyname name uni fun ann))
-> Term tyname name uni fun ann
-> m (Term tyname name uni fun ann)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
-> m (Term tyname name uni fun ann)
forall (m :: * -> *) tyname (uni :: * -> *) ann a.
NormalizeTypeT m tyname uni ann a -> m a
runNormalizeTypeT (NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
 -> m (Term tyname name uni fun ann))
-> (Term tyname name uni fun ann
    -> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann))
-> Term tyname name uni fun ann
-> m (Term tyname name uni fun ann)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term tyname name uni fun ann
-> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
forall tyname (m :: * -> *) (uni :: * -> *) name fun ann.
(HasUnique tyname TypeUnique, MonadQuote m, HasUniApply uni) =>
Term tyname name uni fun ann
-> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
normalizeTypesInM

-- | Normalize every 'Type' in a 'Program'.
normalizeTypesInProgram
    :: (HasUnique tyname TypeUnique, HasUnique name TermUnique, MonadQuote m, HasUniApply uni)
    => Program tyname name uni fun ann -> m (Program tyname name uni fun ann)
normalizeTypesInProgram :: forall tyname name (m :: * -> *) (uni :: * -> *) fun ann.
(HasUnique tyname TypeUnique, HasUnique name TermUnique,
 MonadQuote m, HasUniApply uni) =>
Program tyname name uni fun ann
-> m (Program tyname name uni fun ann)
normalizeTypesInProgram (Program ann
x Version
v Term tyname name uni fun ann
t) = ann
-> Version
-> Term tyname name uni fun ann
-> Program tyname name uni fun ann
forall tyname name (uni :: * -> *) fun ann.
ann
-> Version
-> Term tyname name uni fun ann
-> Program tyname name uni fun ann
Program ann
x Version
v (Term tyname name uni fun ann -> Program tyname name uni fun ann)
-> m (Term tyname name uni fun ann)
-> m (Program tyname name uni fun ann)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
forall tyname name (m :: * -> *) (uni :: * -> *) fun ann.
(HasUnique tyname TypeUnique, HasUnique name TermUnique,
 MonadQuote m, HasUniApply uni) =>
Term tyname name uni fun ann -> m (Term tyname name uni fun ann)
normalizeTypesIn Term tyname name uni fun ann
t

-- | Normalize every 'Type' in a 'Term'.
-- Mirrors the `normalizeTypesInM` of 'PlutusCore.Normalize.Internal', working on PIR.Term instead
normalizeTypesInM
    :: (HasUnique tyname TypeUnique, MonadQuote m, HasUniApply uni)
    => Term tyname name uni fun ann -> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
normalizeTypesInM :: forall tyname (m :: * -> *) (uni :: * -> *) name fun ann.
(HasUnique tyname TypeUnique, MonadQuote m, HasUniApply uni) =>
Term tyname name uni fun ann
-> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
normalizeTypesInM = LensLike
  (WrappedMonad (NormalizeTypeT m tyname uni ann))
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
-> (Term tyname name uni fun ann
    -> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann))
-> Term tyname name uni fun ann
-> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
forall (m :: * -> *) a b.
Monad m =>
LensLike (WrappedMonad m) a b a b -> (b -> m b) -> a -> m b
transformMOf LensLike
  (WrappedMonad (NormalizeTypeT m tyname uni ann))
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
  (Term tyname name uni fun ann)
forall tyname name (uni :: * -> *) fun a (f :: * -> *).
Applicative f =>
(Term tyname name uni fun a -> f (Term tyname name uni fun a))
-> Term tyname name uni fun a -> f (Term tyname name uni fun a)
termSubterms Term tyname name uni fun ann
-> NormalizeTypeT m tyname uni ann (Term tyname name uni fun ann)
forall {name} {fun} {a}.
Term tyname name uni fun a
-> NormalizeTypeT m tyname uni a (Term tyname name uni fun a)
normalizeChildTypes where
    normalizeChildTypes :: Term tyname name uni fun a
-> NormalizeTypeT m tyname uni a (Term tyname name uni fun a)
normalizeChildTypes = (Type tyname uni a
 -> NormalizeTypeT m tyname uni a (Type tyname uni a))
-> Term tyname name uni fun a
-> NormalizeTypeT m tyname uni a (Term tyname name uni fun a)
forall tyname name (uni :: * -> *) fun a (f :: * -> *).
Applicative f =>
(Type tyname uni a -> f (Type tyname uni a))
-> Term tyname name uni fun a -> f (Term tyname name uni fun a)
termSubtypes ((Normalized (Type tyname uni a) -> Type tyname uni a)
-> NormalizeTypeT m tyname uni a (Normalized (Type tyname uni a))
-> NormalizeTypeT m tyname uni a (Type tyname uni a)
forall a b.
(a -> b)
-> NormalizeTypeT m tyname uni a a
-> NormalizeTypeT m tyname uni a b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Normalized (Type tyname uni a) -> Type tyname uni a
forall a. Normalized a -> a
unNormalized (NormalizeTypeT m tyname uni a (Normalized (Type tyname uni a))
 -> NormalizeTypeT m tyname uni a (Type tyname uni a))
-> (Type tyname uni a
    -> NormalizeTypeT m tyname uni a (Normalized (Type tyname uni a)))
-> Type tyname uni a
-> NormalizeTypeT m tyname uni a (Type tyname uni a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type tyname uni a
-> NormalizeTypeT m tyname uni a (Normalized (Type tyname uni a))
forall tyname (uni :: * -> *) (m :: * -> *) ann.
(HasUnique tyname TypeUnique, MonadNormalizeType uni m) =>
Type tyname uni ann
-> NormalizeTypeT
     m tyname uni ann (Normalized (Type tyname uni ann))
normalizeTypeM)