{-# LANGUAGE LambdaCase #-}
module UntypedPlutusCore.Transform.ForceCaseDelay
( forceCaseDelay
)
where
import UntypedPlutusCore.Core
import UntypedPlutusCore.Transform.Simplifier
( SimplifierStage (ForceCaseDelay)
, SimplifierT
, recordSimplification
)
import Control.Lens
forceCaseDelay
:: Monad m
=> Term name uni fun a
-> SimplifierT name uni fun a m (Term name uni fun a)
forceCaseDelay :: forall (m :: * -> *) name (uni :: * -> *) fun a.
Monad m =>
Term name uni fun a
-> SimplifierT name uni fun a m (Term name uni fun a)
forceCaseDelay Term name uni fun a
term = do
let result :: Term name uni fun a
result = ASetter
(Term name uni fun a)
(Term name uni fun a)
(Term name uni fun a)
(Term name uni fun a)
-> (Term name uni fun a -> Term name uni fun a)
-> Term name uni fun a
-> Term name uni fun a
forall a b. ASetter a b a b -> (b -> b) -> a -> b
transformOf ASetter
(Term name uni fun a)
(Term name uni fun a)
(Term name uni fun a)
(Term name uni fun a)
forall name (uni :: * -> *) fun ann (f :: * -> *).
Applicative f =>
(Term name uni fun ann -> f (Term name uni fun ann))
-> Term name uni fun ann -> f (Term name uni fun ann)
termSubterms Term name uni fun a -> Term name uni fun a
forall name (uni :: * -> *) fun a.
Term name uni fun a -> Term name uni fun a
processTerm Term name uni fun a
term
Term name uni fun a
-> SimplifierStage
-> Term name uni fun a
-> SimplifierT name uni fun a m ()
forall (m :: * -> *) name (uni :: * -> *) fun a.
Monad m =>
Term name uni fun a
-> SimplifierStage
-> Term name uni fun a
-> SimplifierT name uni fun a m ()
recordSimplification Term name uni fun a
term SimplifierStage
ForceCaseDelay Term name uni fun a
result
Term name uni fun a
-> SimplifierT name uni fun a m (Term name uni fun a)
forall a. a -> SimplifierT name uni fun a m a
forall (m :: * -> *) a. Monad m => a -> m a
return Term name uni fun a
result
processTerm :: Term name uni fun a -> Term name uni fun a
processTerm :: forall name (uni :: * -> *) fun a.
Term name uni fun a -> Term name uni fun a
processTerm = \case
original :: Term name uni fun a
original@(Force a
_ (Case a
cAnn Term name uni fun a
scrut Vector (Term name uni fun a)
branches)) ->
let mNewBranches :: Maybe (Vector (Term name uni fun a))
mNewBranches = (Term name uni fun a -> Maybe (Term name uni fun a))
-> Vector (Term name uni fun a)
-> Maybe (Vector (Term name uni fun a))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Vector a -> f (Vector b)
traverse Term name uni fun a -> Maybe (Term name uni fun a)
forall name (uni :: * -> *) fun a.
Term name uni fun a -> Maybe (Term name uni fun a)
findDelayUnderLambdas Vector (Term name uni fun a)
branches
in case Maybe (Vector (Term name uni fun a))
mNewBranches of
Just Vector (Term name uni fun a)
newBranches ->
a
-> Term name uni fun a
-> Vector (Term name uni fun a)
-> Term name uni fun a
forall name (uni :: * -> *) fun ann.
ann
-> Term name uni fun ann
-> Vector (Term name uni fun ann)
-> Term name uni fun ann
Case a
cAnn Term name uni fun a
scrut Vector (Term name uni fun a)
newBranches
Maybe (Vector (Term name uni fun a))
Nothing -> Term name uni fun a
original
Term name uni fun a
other -> Term name uni fun a
other
where
findDelayUnderLambdas :: Term name uni fun a -> Maybe (Term name uni fun a)
findDelayUnderLambdas :: forall name (uni :: * -> *) fun a.
Term name uni fun a -> Maybe (Term name uni fun a)
findDelayUnderLambdas = \case
LamAbs a
ann name
var Term name uni fun a
body -> a -> name -> Term name uni fun a -> Term name uni fun a
forall name (uni :: * -> *) fun ann.
ann -> name -> Term name uni fun ann -> Term name uni fun ann
LamAbs a
ann name
var (Term name uni fun a -> Term name uni fun a)
-> Maybe (Term name uni fun a) -> Maybe (Term name uni fun a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Term name uni fun a -> Maybe (Term name uni fun a)
forall name (uni :: * -> *) fun a.
Term name uni fun a -> Maybe (Term name uni fun a)
findDelayUnderLambdas Term name uni fun a
body
Delay a
_ Term name uni fun a
term -> Term name uni fun a -> Maybe (Term name uni fun a)
forall a. a -> Maybe a
Just Term name uni fun a
term
Term name uni fun a
_ -> Maybe (Term name uni fun a)
forall a. Maybe a
Nothing