module Plutarch.Unroll (punrollBound, punrollBound', punrollUnbound, punrollUnboundWhole) where
import Plutarch.Internal.Fix (pfix)
import Plutarch.Internal.PLam (plam)
import Plutarch.Internal.Term (Term, (#$), (:-->))
punrollBound ::
forall a b s.
Integer ->
Term s (a :--> b) ->
(Term s (a :--> b) -> Term s (a :--> b)) ->
Term s (a :--> b)
punrollBound :: forall (a :: PType) (b :: PType) (s :: S).
Integer
-> Term s (a :--> b)
-> (Term s (a :--> b) -> Term s (a :--> b))
-> Term s (a :--> b)
punrollBound Integer
d Term s (a :--> b)
def Term s (a :--> b) -> Term s (a :--> b)
f = Integer
-> (() -> Term s (a :--> b))
-> ((() -> Term s (a :--> b)) -> () -> Term s (a :--> b))
-> ()
-> Term s (a :--> b)
forall (a :: PType) (b :: PType) c (s :: S).
Integer
-> (c -> Term s (a :--> b))
-> ((c -> Term s (a :--> b)) -> c -> Term s (a :--> b))
-> c
-> Term s (a :--> b)
punrollBound' Integer
d (Term s (a :--> b) -> () -> Term s (a :--> b)
forall a b. a -> b -> a
const Term s (a :--> b)
def) (\() -> Term s (a :--> b)
g () -> Term s (a :--> b) -> Term s (a :--> b)
f (() -> Term s (a :--> b)
g ())) ()
punrollBound' ::
forall a b c s.
Integer ->
(c -> Term s (a :--> b)) ->
((c -> Term s (a :--> b)) -> c -> Term s (a :--> b)) ->
c ->
Term s (a :--> b)
punrollBound' :: forall (a :: PType) (b :: PType) c (s :: S).
Integer
-> (c -> Term s (a :--> b))
-> ((c -> Term s (a :--> b)) -> c -> Term s (a :--> b))
-> c
-> Term s (a :--> b)
punrollBound' Integer
0 c -> Term s (a :--> b)
def (c -> Term s (a :--> b)) -> c -> Term s (a :--> b)
_ c
c = c -> Term s (a :--> b)
def c
c
punrollBound' Integer
d c -> Term s (a :--> b)
def (c -> Term s (a :--> b)) -> c -> Term s (a :--> b)
f c
c = (c -> Term s (a :--> b)) -> c -> Term s (a :--> b)
f (Integer
-> (c -> Term s (a :--> b))
-> ((c -> Term s (a :--> b)) -> c -> Term s (a :--> b))
-> c
-> Term s (a :--> b)
forall (a :: PType) (b :: PType) c (s :: S).
Integer
-> (c -> Term s (a :--> b))
-> ((c -> Term s (a :--> b)) -> c -> Term s (a :--> b))
-> c
-> Term s (a :--> b)
punrollBound' (Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) c -> Term s (a :--> b)
def (c -> Term s (a :--> b)) -> c -> Term s (a :--> b)
f) c
c
punrollUnbound :: forall a b s. Integer -> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
punrollUnbound :: forall (a :: PType) (b :: PType) (s :: S).
Integer
-> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
punrollUnbound Integer
0 Term s (a :--> b) -> Term s (a :--> b)
f = Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
forall (s :: S) (a :: PType) (b :: PType).
Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
pfix Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b)) -> Term s (a :--> b)
forall (s :: S) (a :: PType) (b :: PType).
Term s (a :--> b) -> Term s a -> Term s b
#$ (Term s (a :--> b) -> Term s (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b))
forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: PType).
HasCallStack =>
(Term s c -> Term s (a :--> b)) -> Term s (c :--> (a :--> b))
plam Term s (a :--> b) -> Term s (a :--> b)
f
punrollUnbound Integer
d Term s (a :--> b) -> Term s (a :--> b)
f = Term s (a :--> b) -> Term s (a :--> b)
f (Integer
-> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
forall (a :: PType) (b :: PType) (s :: S).
Integer
-> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
punrollUnbound (Integer
d Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
- Integer
1) Term s (a :--> b) -> Term s (a :--> b)
f)
punrollUnboundWhole :: forall a b s. Integer -> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
punrollUnboundWhole :: forall (a :: PType) (b :: PType) (s :: S).
Integer
-> (Term s (a :--> b) -> Term s (a :--> b)) -> Term s (a :--> b)
punrollUnboundWhole Integer
d Term s (a :--> b) -> Term s (a :--> b)
f = Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
forall (s :: S) (a :: PType) (b :: PType).
Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
pfix Term s (((a :--> b) :--> (a :--> b)) :--> (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b)) -> Term s (a :--> b)
forall (s :: S) (a :: PType) (b :: PType).
Term s (a :--> b) -> Term s a -> Term s b
#$ (Term s (a :--> b) -> Term s (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b))
forall a (b :: PType) (s :: S) (c :: PType).
(PLamN a b s, HasCallStack) =>
(Term s c -> a) -> Term s (c :--> b)
forall (c :: PType).
HasCallStack =>
(Term s c -> Term s (a :--> b)) -> Term s (c :--> (a :--> b))
plam ((Term s (a :--> b) -> Term s (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b)))
-> (Term s (a :--> b) -> Term s (a :--> b))
-> Term s ((a :--> b) :--> (a :--> b))
forall a b. (a -> b) -> a -> b
$ \Term s (a :--> b)
r -> Integer
-> Term s (a :--> b)
-> (Term s (a :--> b) -> Term s (a :--> b))
-> Term s (a :--> b)
forall (a :: PType) (b :: PType) (s :: S).
Integer
-> Term s (a :--> b)
-> (Term s (a :--> b) -> Term s (a :--> b))
-> Term s (a :--> b)
punrollBound Integer
d Term s (a :--> b)
r Term s (a :--> b) -> Term s (a :--> b)
f