{-# OPTIONS_GHC -Wno-orphans #-}
module Lorentz.Zip
( ZipInstr (..)
, zipInstr
, unzipInstr
, ZipInstrs
, zippingStack
, unzippingStack
) where
import Prelude hiding (drop)
import Lorentz.Annotation
import Lorentz.Base
import Michelson.Typed
import Michelson.Untyped (noAnn)
(##) :: (a :-> b) -> (b :-> c) -> (a :-> c)
I Instr (ToTs a) (ToTs b)
l ## :: (a :-> b) -> (b :-> c) -> a :-> c
## I Instr (ToTs b) (ToTs c)
r = Instr (ToTs a) (ToTs c) -> a :-> c
forall (inp :: [*]) (out :: [*]).
Instr (ToTs inp) (ToTs out) -> inp :-> out
I (Instr (ToTs a) (ToTs b)
-> Instr (ToTs b) (ToTs c) -> Instr (ToTs a) (ToTs c)
forall (a :: [T]) (b :: [T]) (c :: [T]).
Instr a b -> Instr b c -> Instr a c
seqOpt Instr (ToTs a) (ToTs b)
l Instr (ToTs b) (ToTs c)
r)
a :-> b
l ## b :-> c
r = a :-> b
l (a :-> b) -> (b :-> c) -> a :-> c
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
# b :-> c
r
seqOpt :: Instr a b -> Instr b c -> Instr a c
seqOpt :: Instr a b -> Instr b c -> Instr a c
seqOpt Instr a b
l Instr b c
r =
case Instr a b
l of
Instr a b
Nop -> Instr a c
Instr b c
r
DIP Instr a c
Nop -> Instr a c
Instr b c
r
Instr a b
x -> case Instr b c
r of
Instr b c
Nop -> Instr a b
Instr a c
x
DIP Instr a c
Nop -> Instr a b
Instr a c
x
Instr b c
_ -> Instr a b
l Instr a b -> Instr b c -> Instr a c
forall (a :: [T]) (b :: [T]) (c :: [T]).
Instr a b -> Instr b c -> Instr a c
`Seq` Instr b c
r
class (KnownIsoT (ZippedStack s)) => ZipInstr (s :: [Type]) where
type ZippedStack s :: Type
zipInstrTyped :: Instr (ToTs s) '[ToT (ZippedStack s)]
unzipInstrTyped :: Instr '[ToT (ZippedStack s)] (ToTs s)
zipInstr :: forall s. ZipInstr s => s :-> '[ZippedStack s]
zipInstr :: s :-> '[ZippedStack s]
zipInstr = Instr (ToTs s) (ToTs '[ZippedStack s]) -> s :-> '[ZippedStack s]
forall (inp :: [*]) (out :: [*]).
Instr (ToTs inp) (ToTs out) -> inp :-> out
I (ZipInstr s => Instr (ToTs s) '[ToT (ZippedStack s)]
forall (s :: [*]).
ZipInstr s =>
Instr (ToTs s) '[ToT (ZippedStack s)]
zipInstrTyped @s)
unzipInstr :: forall s. ZipInstr s => '[ZippedStack s] :-> s
unzipInstr :: '[ZippedStack s] :-> s
unzipInstr = Instr (ToTs '[ZippedStack s]) (ToTs s) -> '[ZippedStack s] :-> s
forall (inp :: [*]) (out :: [*]).
Instr (ToTs inp) (ToTs out) -> inp :-> out
I (ZipInstr s => Instr '[ToT (ZippedStack s)] (ToTs s)
forall (s :: [*]).
ZipInstr s =>
Instr '[ToT (ZippedStack s)] (ToTs s)
unzipInstrTyped @s)
instance ZipInstr '[] where
type ZippedStack '[] = ()
zipInstrTyped :: Instr (ToTs '[]) '[ToT (ZippedStack '[])]
zipInstrTyped = Instr (ToTs '[]) '[ToT (ZippedStack '[])]
forall (inp :: [T]). Instr inp ('TUnit : inp)
UNIT
unzipInstrTyped :: Instr '[ToT (ZippedStack '[])] (ToTs '[])
unzipInstrTyped = Instr '[ToT (ZippedStack '[])] (ToTs '[])
forall (a :: T) (out :: [T]). Instr (a : out) out
DROP
instance (KnownIsoT a) => ZipInstr '[a] where
type ZippedStack '[a] = a
zipInstrTyped :: Instr (ToTs '[a]) '[ToT (ZippedStack '[a])]
zipInstrTyped = Instr (ToTs '[a]) '[ToT (ZippedStack '[a])]
forall (inp :: [T]). Instr inp inp
Nop
unzipInstrTyped :: Instr '[ToT (ZippedStack '[a])] (ToTs '[a])
unzipInstrTyped = Instr '[ToT (ZippedStack '[a])] (ToTs '[a])
forall (inp :: [T]). Instr inp inp
Nop
instance (ZipInstr (b ': s), KnownIsoT a) => ZipInstr (a ': b ': s) where
type ZippedStack (a ': b ': s) = (a, ZippedStack (b ': s))
zipInstrTyped :: Instr (ToTs (a : b : s)) '[ToT (ZippedStack (a : b : s))]
zipInstrTyped = Instr (ToT b : ToTs s) '[ToT (ZippedStack (b : s))]
-> Instr
(ToT a : ToT b : ToTs s) '[ToT a, ToT (ZippedStack (b : s))]
forall (a :: [T]) (c :: [T]) (b :: T).
Instr a c -> Instr (b : a) (b : c)
DIP (ZipInstr (b : s) =>
Instr (ToTs (b : s)) '[ToT (ZippedStack (b : s))]
forall (s :: [*]).
ZipInstr s =>
Instr (ToTs s) '[ToT (ZippedStack s)]
zipInstrTyped @(b ': s)) Instr (ToT a : ToT b : ToTs s) '[ToT a, ToT (ZippedStack (b : s))]
-> Instr
'[ToT a, ToT (ZippedStack (b : s))]
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
-> Instr
(ToT a : ToT b : ToTs s)
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
forall (a :: [T]) (b :: [T]) (c :: [T]).
Instr a b -> Instr b c -> Instr a c
`seqOpt` Instr
'[ToT a, ToT (ZippedStack (b : s))]
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
forall (i :: [T]) (o :: [T]) (a :: T) (b :: T) (s :: [T]).
(i ~ (a : b : s), o ~ ('TPair a b : s)) =>
Instr i o
PAIR
unzipInstrTyped :: Instr '[ToT (ZippedStack (a : b : s))] (ToTs (a : b : s))
unzipInstrTyped = Instr
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
'[ToT a, ToT (ZippedStack (b : s))]
forall (i :: [T]) (o :: [T]) (a :: T) (b :: T) (s :: [T]).
(i ~ ('TPair a b : s), o ~ (a : b : s)) =>
Instr i o
UNPAIR Instr
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
'[ToT a, ToT (ZippedStack (b : s))]
-> Instr
'[ToT a, ToT (ZippedStack (b : s))] (ToT a : ToT b : ToTs s)
-> Instr
'[ 'TPair (ToT a) (ToT (ZippedStack (b : s)))]
(ToT a : ToT b : ToTs s)
forall (a :: [T]) (b :: [T]) (c :: [T]).
Instr a b -> Instr b c -> Instr a c
`seqOpt` Instr '[ToT (ZippedStack (b : s))] (ToT b : ToTs s)
-> Instr
'[ToT a, ToT (ZippedStack (b : s))] (ToT a : ToT b : ToTs s)
forall (a :: [T]) (c :: [T]) (b :: T).
Instr a c -> Instr (b : a) (b : c)
DIP (ZipInstr (b : s) =>
Instr '[ToT (ZippedStack (b : s))] (ToTs (b : s))
forall (s :: [*]).
ZipInstr s =>
Instr '[ToT (ZippedStack s)] (ToTs s)
unzipInstrTyped @(b ': s))
type ZipInstrs ss = Each '[ZipInstr] ss
zippingStack
:: ZipInstrs [inp, out]
=> inp :-> out -> Lambda (ZippedStack inp) (ZippedStack out)
zippingStack :: (inp :-> out) -> Lambda (ZippedStack inp) (ZippedStack out)
zippingStack inp :-> out
code = '[ZippedStack inp] :-> inp
forall (s :: [*]). ZipInstr s => '[ZippedStack s] :-> s
unzipInstr ('[ZippedStack inp] :-> inp)
-> (inp :-> out) -> '[ZippedStack inp] :-> out
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## inp :-> out
code ('[ZippedStack inp] :-> out)
-> (out :-> '[ZippedStack out])
-> Lambda (ZippedStack inp) (ZippedStack out)
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## out :-> '[ZippedStack out]
forall (s :: [*]). ZipInstr s => s :-> '[ZippedStack s]
zipInstr
unzippingStack
:: ZipInstrs [inp, out]
=> Lambda (ZippedStack inp) (ZippedStack out) -> inp :-> out
unzippingStack :: Lambda (ZippedStack inp) (ZippedStack out) -> inp :-> out
unzippingStack Lambda (ZippedStack inp) (ZippedStack out)
code = inp :-> '[ZippedStack inp]
forall (s :: [*]). ZipInstr s => s :-> '[ZippedStack s]
zipInstr (inp :-> '[ZippedStack inp])
-> Lambda (ZippedStack inp) (ZippedStack out)
-> inp :-> '[ZippedStack out]
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## Lambda (ZippedStack inp) (ZippedStack out)
code (inp :-> '[ZippedStack out])
-> ('[ZippedStack out] :-> out) -> inp :-> out
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## '[ZippedStack out] :-> out
forall (s :: [*]). ZipInstr s => '[ZippedStack s] :-> s
unzipInstr
instance (WellTypedToT (ZippedStack inp), WellTypedToT (ZippedStack out), ZipInstr inp, ZipInstr out) => IsoValue (inp :-> out) where
type ToT (inp :-> out) = 'TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out))
toVal :: (inp :-> out) -> Value (ToT (inp :-> out))
toVal inp :-> out
i = RemFail Instr '[ToT (ZippedStack inp)] '[ToT (ZippedStack out)]
-> Value'
Instr ('TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out)))
forall (inp :: T) (out :: T) (instr :: [T] -> [T] -> *).
(KnownT inp, KnownT out,
forall (i :: [T]) (o :: [T]). Show (instr i o),
forall (i :: [T]) (o :: [T]). Eq (instr i o),
forall (i :: [T]) (o :: [T]). NFData (instr i o)) =>
RemFail instr '[inp] '[out] -> Value' instr ('TLambda inp out)
VLam (RemFail Instr '[ToT (ZippedStack inp)] '[ToT (ZippedStack out)]
-> Value'
Instr ('TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out))))
-> (('[ZippedStack inp] :-> '[ZippedStack out])
-> RemFail Instr '[ToT (ZippedStack inp)] '[ToT (ZippedStack out)])
-> ('[ZippedStack inp] :-> '[ZippedStack out])
-> Value'
Instr ('TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('[ZippedStack inp] :-> '[ZippedStack out])
-> RemFail Instr '[ToT (ZippedStack inp)] '[ToT (ZippedStack out)]
forall (inp :: [*]) (out :: [*]).
(inp :-> out) -> RemFail Instr (ToTs inp) (ToTs out)
unLorentzInstr (('[ZippedStack inp] :-> '[ZippedStack out])
-> Value'
Instr ('TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out))))
-> ('[ZippedStack inp] :-> '[ZippedStack out])
-> Value'
Instr ('TLambda (ToT (ZippedStack inp)) (ToT (ZippedStack out)))
forall a b. (a -> b) -> a -> b
$ (inp :-> out) -> '[ZippedStack inp] :-> '[ZippedStack out]
forall (inp :: [*]) (out :: [*]).
ZipInstrs '[inp, out] =>
(inp :-> out) -> Lambda (ZippedStack inp) (ZippedStack out)
zippingStack inp :-> out
i
fromVal :: Value (ToT (inp :-> out)) -> inp :-> out
fromVal (VLam RemFail Instr '[inp] '[out]
i) = inp :-> '[ZippedStack inp]
forall (s :: [*]). ZipInstr s => s :-> '[ZippedStack s]
zipInstr (inp :-> '[ZippedStack inp])
-> ('[ZippedStack inp] :-> '[ZippedStack out])
-> inp :-> '[ZippedStack out]
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## RemFail Instr (ToTs '[ZippedStack inp]) (ToTs '[ZippedStack out])
-> '[ZippedStack inp] :-> '[ZippedStack out]
forall (inp :: [*]) (out :: [*]).
RemFail Instr (ToTs inp) (ToTs out) -> inp :-> out
LorentzInstr RemFail Instr '[inp] '[out]
RemFail Instr (ToTs '[ZippedStack inp]) (ToTs '[ZippedStack out])
i (inp :-> '[ZippedStack out])
-> ('[ZippedStack out] :-> out) -> inp :-> out
forall (a :: [*]) (b :: [*]) (c :: [*]).
(a :-> b) -> (b :-> c) -> a :-> c
## '[ZippedStack out] :-> out
forall (s :: [*]). ZipInstr s => '[ZippedStack s] :-> s
unzipInstr
instance
( HasAnnotation (ZippedStack i)
, HasAnnotation (ZippedStack o)
)
=>
HasAnnotation (i :-> o)
where
getAnnotation :: FollowEntrypointFlag -> Notes (ToT (i :-> o))
getAnnotation FollowEntrypointFlag
b = TypeAnn
-> Notes (ToT (ZippedStack i))
-> Notes (ToT (ZippedStack o))
-> Notes ('TLambda (ToT (ZippedStack i)) (ToT (ZippedStack o)))
forall (p :: T) (q :: T).
TypeAnn -> Notes p -> Notes q -> Notes ('TLambda p q)
NTLambda TypeAnn
forall k (a :: k). Annotation a
noAnn
(FollowEntrypointFlag -> Notes (ToT (ZippedStack i))
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @(ZippedStack i) FollowEntrypointFlag
b)
(FollowEntrypointFlag -> Notes (ToT (ZippedStack o))
forall a. HasAnnotation a => FollowEntrypointFlag -> Notes (ToT a)
getAnnotation @(ZippedStack o) FollowEntrypointFlag
b)