lorentz 0.13.3 → 0.13.4
raw patch · 11 files changed
+278/−82 lines, 11 files
Files
- CHANGES.md +31/−1
- lorentz.cabal +1/−1
- src/Lorentz/Entrypoints/Doc.hs +195/−43
- src/Lorentz/Entrypoints/Impl.hs +9/−0
- src/Lorentz/Errors.hs +0/−11
- src/Lorentz/Ext.hs +1/−1
- src/Lorentz/Macro.hs +13/−12
- src/Lorentz/Run/Simple.hs +10/−5
- src/Lorentz/UParam.hs +1/−5
- src/Lorentz/Value.hs +1/−1
- src/Lorentz/Zip.hs +16/−2
CHANGES.md view
@@ -1,6 +1,28 @@ <!-- Unreleased: append new entries here --> +0.13.4+======+* [!1078](https://gitlab.com/morley-framework/morley/-/merge_requests/1078)+ Option to flatten EpdRecursive entrypoints in autodoc+ + New entrypoint kind `FlattenedEntrypointsKindHiding`, which flattens+ entrypoints in autodoc and allows hiding specific constructors. For other+ intents it's the same as `PlainEntrypointsKind`.+ + Convenience synonym `FlattenedEntrypointsKind` for cases where no hiding+ is necessary.+ + New convenience functions `entryCaseFlattened` and+ `entryCaseFlattenedHiding`.+ + Deprecate redundant `constructDEpArg`, use `mkDEntrypointArgSimple` instead.+* [!1104](https://gitlab.com/morley-framework/morley/-/merge_requests/1104)+ Use clearer notation for (-$)+ + Introduce new data types `ZippedStackRepr a b = a ::: b`+ and `ZSNil = ZSNil`, isomorphic to '(a, b)' and '()' respectively,+ to represent a zipped stack.+* [!1082](https://gitlab.com/morley-framework/morley/-/merge_requests/1082)+ Fix/drop/comment noncanonical Show instances+* [!841](https://gitlab.com/morley-framework/morley/-/merge_requests/841)+ Make entrypoints derivation work with void-like entrypoint arguments.+ 0.13.3 ====== * [!1100](https://gitlab.com/morley-framework/morley/-/merge_requests/1100)@@ -155,7 +177,15 @@ instance implemented via `storeFieldOpsADT`. * If you have storage which is directly a map, use `this` instead of label to access the map. * If you have an instance for a complex storage which is not represented as simple ADT,- turn this instance into overlappable one.+ turn this instance into overlappable one. Make sure that `name` type parameter is of+ concrete type to avoid "overlapping instances" error.+ * The pattern when a datatype transparently provides access to its inner fields via an+ overlapping instance - may not work smoothly and produce "overlapping instances" error.+ To mitigate this do one of the following:+ * Specify the kind of `name` type parameter in your overlapping instance to be concrete+ (i.e. `Symbol`).+ * Use the new functionality to access the nested field by a fully qualified name.+ * [!807](https://gitlab.com/morley-framework/morley/-/merge_requests/807) + Add some instances to `BigMap` and `TAddress` types. * [!787](https://gitlab.com/morley-framework/morley/-/merge_requests/787)
lorentz.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: lorentz-version: 0.13.3+version: 0.13.4 synopsis: EDSL for the Michelson Language description: Lorentz is a powerful meta-programming tool which allows one to write Michelson contracts directly in Haskell. It has the same instructions as Michelson, but operates on Haskell values and allows one to use Haskell features. category: Language
src/Lorentz/Entrypoints/Doc.hs view
@@ -2,6 +2,7 @@ -- SPDX-License-Identifier: LicenseRef-MIT-OA {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}+{-# LANGUAGE InstanceSigs #-} -- | Utilities for declaring and documenting entry points. module Lorentz.Entrypoints.Doc@@ -12,6 +13,8 @@ , DEntrypointReference (..) , EntryArrow (..) , PlainEntrypointsKind+ , FlattenedEntrypointsKind+ , FlattenedEntrypointsKindHiding , CommonContractBehaviourKind , CommonEntrypointsBehaviourKind , diEntrypointToMarkdown@@ -38,22 +41,25 @@ , areFinalizedParamBuildingSteps , entryCaseSimple_ , entryCaseSimple+ , entryCaseFlattened_+ , entryCaseFlattened+ , entryCaseFlattenedHiding_+ , entryCaseFlattenedHiding , RequireFlatParamEps , RequireFlatEpDerivation ) where -import Debug qualified (show)- import Control.Lens.Cons (_head) import Data.Char (toLower) import Data.Constraint (Dict(..)) import Data.Map qualified as Map+import Data.Singletons (fromSing) import Data.Text qualified as T import Data.Vinyl.Core (RMap, rappend)+import Fcf (IsJust, type (@@)) import Fmt (Buildable(..), build, fmt, listF) import GHC.Generics ((:+:)) import GHC.Generics qualified as G-import Text.Show qualified import Lorentz.ADT import Lorentz.Annotation@@ -140,17 +146,43 @@ -- All such entrypoints will be placed under the same "entrypoints" section, -- and this instance defines characteristics of this section. class Typeable ep => EntrypointKindHasDoc (ep :: Type) where+ -- | Can be used to make a kind equivalent to some other kind;+ -- if changing this, 'entrypointKindPos' and 'entrypointKindSectionName'+ -- will be ignored.+ type EntrypointKindOverride ep+ type EntrypointKindOverride ep = ep++ -- | Implement this when specifying 'EntrypointKindOverride'.+ -- This should never be normally used, but because @MINIMAL@ pragma+ -- can't specify type families, we use this hack.+ --+ -- Default implementation is a bottom (i.e. a runtime error).+ --+ -- If implemented, it should be+ --+ -- > entrypointKindOverrideSpecified = Dict+ entrypointKindOverrideSpecified :: Dict ((EntrypointKindOverride ep == ep) ~ False)+ entrypointKindOverrideSpecified = error "Called entrypointKindOverrideSpecified"+ -- | Position of the respective entrypoints section in the doc. -- This shares the same positions space with all other doc items. entrypointKindPos :: Natural+ default entrypointKindPos :: EntrypointKindHasDoc (EntrypointKindOverride ep) => Natural+ entrypointKindPos = entrypointKindPos @(EntrypointKindOverride ep) -- | Name of the respective entrypoints section. entrypointKindSectionName :: Text+ default entrypointKindSectionName :: EntrypointKindHasDoc (EntrypointKindOverride ep) => Text+ entrypointKindSectionName = entrypointKindSectionName @(EntrypointKindOverride ep) -- | Description in the respective entrypoints section. entrypointKindSectionDescription :: Maybe Markdown entrypointKindSectionDescription = Nothing + {-# MINIMAL entrypointKindOverrideSpecified | (entrypointKindPos, entrypointKindSectionName) #-}++{-# WARNING entrypointKindOverrideSpecified "Normally you should never need to use this function" #-}+ instance EntrypointKindHasDoc ep => DocItem (DEntrypoint ep) where type DocItemPlacement (DEntrypoint ep) = 'DocItemInlined type DocItemReferenced (DEntrypoint ep) = 'True@@ -180,6 +212,34 @@ entrypointKindPos = 1000 entrypointKindSectionName = "Entrypoints" +-- | Special entrypoint kind that flattens one level of recursive entrypoints.+--+-- With 'EpdRecursive', intermediary nodes are hidden from documentation.+--+-- With 'EpdDelegate', intermediary nodes will still be shown.+--+-- Any entrypoints can be omitted from docs by listing those in the type+-- parameter (which is especially helpful with 'EpdDelegate').+--+-- For other entrypoint derivation strategies (e.g. 'EpdPlain'), behaves like+-- 'PlainEntrypointsKind' (with the exception of hiding entrypoints from docs)+--+-- If you have several levels of recursion, each level will need to have this+-- kind.+--+-- Note that list of entrypoints to be hidden is not checked by default. Use+-- 'entryCaseFlattenedHiding' to have a static check that entrypoints to be+-- hidden do indeed exist.+data FlattenedEntrypointsKindHiding (hiddenEntrypoints :: [Symbol])++-- | A convenience type synonym for 'FlattenedEntrypointsKindHiding' not hiding+-- any entrypoitns.+type FlattenedEntrypointsKind = FlattenedEntrypointsKindHiding '[]++instance Typeable heps => EntrypointKindHasDoc (FlattenedEntrypointsKindHiding heps) where+ type EntrypointKindOverride (FlattenedEntrypointsKindHiding heps) = PlainEntrypointsKind+ entrypointKindOverrideSpecified = Dict+ -- | Describes the behaviour common for all entrypoints. -- -- For instance, if your contract runs some checks before calling any@@ -236,11 +296,6 @@ instance Buildable ParamBuilder where build = pbSample -instance Show ParamBuilder where- show (ParamBuilder pb) =- -- Using @'x'@ symbol here because unicode does not render well in 'show'- "ParamBuilder " <> Debug.show (pb "x")- instance Eq ParamBuilder where (==) = (==) `on` pbSample @@ -251,7 +306,7 @@ -- ^ How to construct parameter in Haskell code. , pbdMichelson :: ParamBuilder -- ^ How to construct parameter working on raw Michelson.- } deriving stock (Show, Eq)+ } deriving stock (Eq) -- | Describes a parameter building step. --@@ -274,7 +329,7 @@ -- It contains dummy 'ParamBuildingStep's which were assigned before -- entrypoints were taken into account. | PbsUncallable [ParamBuildingStep]- deriving stock (Show, Eq)+ deriving stock (Eq) instance Buildable ParamBuildingStep where build = \case@@ -315,16 +370,9 @@ -- into @Service1@ constructor. } -constructDEpArg- :: forall arg.- ( NiceParameter arg- , TypeHasDoc arg- )- => DEntrypointArg-constructDEpArg = DEntrypointArg- { epaArg = Just $ SomeEntrypointArg (Proxy @arg)- , epaBuilding = []- }+constructDEpArg :: forall arg. (NiceParameter arg, TypeHasDoc arg) => DEntrypointArg+constructDEpArg = mkDEntrypointArgSimple @arg+{-# DEPRECATED constructDEpArg "Use `mkDEntrypointArgSimple` instead" #-} emptyDEpArg :: DEntrypointArg emptyDEpArg = DEntrypointArg@@ -335,12 +383,7 @@ mkDEpUType :: forall t. HasAnnotation t => Untyped.Ty mkDEpUType = mkUType (getAnnotation @t FollowEntrypoint) -mkDEntrypointArgSimple- :: forall t.- ( NiceParameter t- , TypeHasDoc t- )- => DEntrypointArg+mkDEntrypointArgSimple :: forall t. (NiceParameter t, TypeHasDoc t) => DEntrypointArg mkDEntrypointArgSimple = DEntrypointArg { epaArg = Just $ SomeEntrypointArg (Proxy @t) , epaBuilding = []@@ -443,7 +486,7 @@ => DeriveCtorFieldDoc con ('OneField ty) where- deriveCtorFieldDoc = constructDEpArg @ty+ deriveCtorFieldDoc = mkDEntrypointArgSimple @ty -- | Add necessary documentation to entry points. documentEntrypoints@@ -451,16 +494,20 @@ DocumentEntrypoints kind a => Rec (CaseClauseL inp out) (CaseClauses a) -> Rec (CaseClauseL inp out) (CaseClauses a)-documentEntrypoints = gDocumentEntrypoints @kind @(G.Rep a) (ParamBuilder id)+documentEntrypoints =+ gDocumentEntrypoints @(BuildEPTree' a) @kind @(G.Rep a) $+ ParamBuilder id -- | Constraint for 'documentEntrypoints'. type DocumentEntrypoints kind a =- (Generic a, GDocumentEntrypoints kind (G.Rep a))+ (Generic a, GDocumentEntrypoints (BuildEPTree' a) kind (G.Rep a)) +type BuildEPTree' a = BuildEPTree (GetParameterEpDerivation a) a+ -- | Traverse entry points and add parameter building step (which describes -- necessity to wrap parameter into some constructor of the given datatype) -- to all parameters described within given code.-class GDocumentEntrypoints (kind :: Type) (x :: Type -> Type) where+class GDocumentEntrypoints (ept :: EPTree) (kind :: Type) (x :: Type -> Type) where -- | Add corresponding parameter building step. -- -- First argument is accumulator for Michelson description of the building step.@@ -469,38 +516,72 @@ -> Rec (CaseClauseL inp out) (GCaseClauses x) -> Rec (CaseClauseL inp out) (GCaseClauses x) -instance GDocumentEntrypoints kind x => GDocumentEntrypoints kind (G.D1 i x) where- gDocumentEntrypoints = gDocumentEntrypoints @kind @x+instance GDocumentEntrypoints ept kind x => GDocumentEntrypoints ept kind (G.D1 i x) where+ gDocumentEntrypoints = gDocumentEntrypoints @ept @kind @x -instance ( GDocumentEntrypoints kind x, GDocumentEntrypoints kind y+instance ( GDocumentEntrypoints eptl kind x, GDocumentEntrypoints eptr kind y , RSplit (GCaseClauses x) (GCaseClauses y) ) =>- GDocumentEntrypoints kind (x :+: y) where+ GDocumentEntrypoints ('EPNode eptl eptr) kind (x :+: y) where gDocumentEntrypoints (ParamBuilder michDesc) clauses = let (lclauses, rclauses) = rsplit @CaseClauseParam @(GCaseClauses x) clauses- in gDocumentEntrypoints @kind @x+ in gDocumentEntrypoints @eptl @kind @x (ParamBuilder $ \a -> michDesc $ "Left (" <> a <> ")") lclauses `rappend`- gDocumentEntrypoints @kind @y+ gDocumentEntrypoints @eptr @kind @y (ParamBuilder $ \a -> michDesc $ "Right (" <> a <> ")") rclauses -instance ( 'CaseClauseParam ctor cf ~ GCaseBranchInput ctor x+instance {-# OVERLAPPABLE #-}+ ( 'CaseClauseParam ctor cf ~ GCaseBranchInput ctor x , KnownSymbol ctor- , DocItem (DEntrypoint kind)+ , DocItem (DEntrypoint (EntrypointKindOverride kind)) , DeriveCtorFieldDoc ctor cf ) =>- GDocumentEntrypoints kind (G.C1 ('G.MetaCons ctor _1 _2) x) where+ GDocumentEntrypoints ept kind (G.C1 ('G.MetaCons ctor _1 _2) x) where gDocumentEntrypoints michDesc (CaseClauseL clause :& RNil) = let entrypointName = toText $ symbolVal (Proxy @ctor) psteps = mkPbsWrapIn entrypointName michDesc addDoc instr = clarifyParamBuildingSteps psteps $- docGroup (DEntrypoint @kind entrypointName) $+ docGroup (DEntrypoint @(EntrypointKindOverride kind) entrypointName) $ doc (deriveCtorFieldDoc @ctor @cf) # instr in CaseClauseL (addDoc clause) :& RNil +instance ( 'CaseClauseParam ctor cf ~ GCaseBranchInput ctor x+ , KnownSymbol ctor+ ) =>+ GDocumentEntrypoints ('EPNode a b) (FlattenedEntrypointsKindHiding _heps)+ (G.C1 ('G.MetaCons ctor _1 _2) x) where+ gDocumentEntrypoints michDesc (CaseClauseL clause :& RNil) =+ let entrypointName = toText $ symbolVal (Proxy @ctor)+ psteps = mkPbsWrapIn entrypointName michDesc+ in CaseClauseL (clarifyParamBuildingSteps psteps clause) :& RNil++instance {-# OVERLAPPABLE #-}+ ( 'CaseClauseParam ctor cf ~ GCaseBranchInput ctor x+ , KnownSymbol ctor+ , DeriveCtorFieldDoc ctor cf+ , T.SingI heps+ ) =>+ GDocumentEntrypoints ept (FlattenedEntrypointsKindHiding heps)+ (G.C1 ('G.MetaCons ctor _1 _2) x) where+ gDocumentEntrypoints michDesc (CaseClauseL clause :& RNil) =+ let epName = toText $ symbolVal (Proxy @ctor)+ psteps = mkPbsWrapIn epName michDesc+ hiddenEps = fromSing $ T.sing @heps+ epDoc instr+ | epName `elem` hiddenEps = instr+ | otherwise =+ docGroup (DEntrypoint @PlainEntrypointsKind epName)+ (doc (deriveCtorFieldDoc @ctor @cf))+ # instr+ addDoc instr =+ clarifyParamBuildingSteps psteps $+ epDoc instr+ in CaseClauseL (addDoc clause) :& RNil+ -- | Like 'case_', to be used for pattern-matching on a parameter -- or its part. --@@ -543,7 +624,7 @@ documentEntrypoint instr = let entrypointName = toText $ symbolVal (Proxy @epName) in docGroup (DEntrypoint @kind entrypointName) $- doc (constructDEpArg @param) # instr+ doc (mkDEntrypointArgSimple @param) # instr -- | Provides arror for convenient entrypoint documentation class EntryArrow kind name body where@@ -650,6 +731,7 @@ PbsUncallable{} -> True in any hasFinalizationTraces +-- | Version of 'entryCase_' for contracts with flat parameter. entryCaseSimple_ :: forall cp out inp. ( InstrCaseC cp@@ -664,8 +746,7 @@ where _reqFlat = Dict @(RequireFlatEpDerivation cp (GetParameterEpDerivation cp)) --- | Version of 'entryCase' for contracts with flat parameter, use it when you--- need only one 'entryCase' all over the contract implementation.+-- | Version of 'entryCase' for contracts with flat parameter. entryCaseSimple :: forall cp out inp clauses. ( CaseTC cp out inp clauses@@ -675,6 +756,68 @@ => IsoRecTuple clauses -> cp : inp :-> out entryCaseSimple = entryCaseSimple_ . recFromTuple +-- | Version of 'entryCase_' for contracts with recursive parameter that needs+-- to be flattened. Use it with 'EpdRecursive' when you don't need intermediary+-- nodes in autodoc.+entryCaseFlattened_+ :: forall cp out inp.+ ( InstrCaseC cp+ , RMap (CaseClauses cp)+ , DocumentEntrypoints FlattenedEntrypointsKind cp+ )+ => Rec (CaseClauseL inp out) (CaseClauses cp)+ -> cp : inp :-> out+entryCaseFlattened_ =+ entryCase_ (Proxy @FlattenedEntrypointsKind)++-- | Version of 'entryCase' for contracts with recursive parameter that needs+-- to be flattened. Use it with 'EpdRecursive' when you don't need intermediary+-- nodes in autodoc.+entryCaseFlattened+ :: forall cp out inp clauses.+ ( CaseTC cp out inp clauses+ , DocumentEntrypoints FlattenedEntrypointsKind cp+ )+ => IsoRecTuple clauses -> cp : inp :-> out+entryCaseFlattened = entryCaseFlattened_ . recFromTuple++-- | Version of 'entryCase_' for contracts with recursive delegate parameter that needs+-- to be flattened. Use it with 'EpdDelegate' when you don't need hierarchical+-- entrypoints in autodoc. You can also hide particular entrypoints with the+-- type parameter. Consider using 'entryCaseFlattened_' if you don't want+-- to hide any entrypoints.+entryCaseFlattenedHiding_+ :: forall heps cp out inp.+ ( InstrCaseC cp+ , RMap (CaseClauses cp)+ , DocumentEntrypoints (FlattenedEntrypointsKindHiding heps) cp+ , HasEntrypoints (ParameterEntrypointsDerivation cp) cp heps+ )+ => Rec (CaseClauseL inp out) (CaseClauses cp)+ -> cp : inp :-> out+entryCaseFlattenedHiding_ =+ entryCase_ (Proxy @(FlattenedEntrypointsKindHiding heps))+ where+ _reqHasEps = Dict @(HasEntrypoints (ParameterEntrypointsDerivation cp) cp heps)++-- | Version of 'entryCase' for contracts with recursive delegate parameter that needs+-- to be flattened. Use it with 'EpdDelegate' when you don't need hierarchical+-- entrypoints in autodoc. You can also hide particular entrypoints with the+-- first type parameter. Consider using 'entryCaseFlattened' if you don't want+-- to hide any entrypoints.+--+-- @+-- entryCaseFlattenedHiding @'["Ep1", "Ep2"] ...+-- @+entryCaseFlattenedHiding+ :: forall heps cp out inp clauses.+ ( CaseTC cp out inp clauses+ , DocumentEntrypoints (FlattenedEntrypointsKindHiding heps) cp+ , HasEntrypoints (ParameterEntrypointsDerivation cp) cp heps+ )+ => IsoRecTuple clauses -> cp : inp :-> out+entryCaseFlattenedHiding = entryCaseFlattenedHiding_ @heps . recFromTuple+ type family RequireFlatParamEps cp :: Constraint where RequireFlatParamEps cp = ( NiceParameterFull cp@@ -691,6 +834,15 @@ 'Text "For parameter `" ':<>: 'ShowType cp ':<>: 'Text "`" ':$$: 'Text "With entrypoints derivation way `" ':<>: 'ShowType deriv ':<>: 'Text "`" )++type family HasEntrypoints mode cp syms :: Constraint where+ HasEntrypoints mode cp (x ': xs) =+ If (IsJust @@ (EpdLookupEntrypoint mode cp @@ x))+ (HasEntrypoints mode cp xs)+ (TypeError+ ('Text "Parameter type " ':<>: 'ShowType cp+ ':<>: 'Text " does not contain entrypoint " ':<>: 'ShowType x))+ HasEntrypoints _ _ '[] = () --------------------------- -- Helper
src/Lorentz/Entrypoints/Impl.hs view
@@ -169,6 +169,8 @@ GBuildEntrypointsTree mode x GBuildEntrypointsTree mode (x G.:+: y) = 'EPNode (GBuildEntrypointsTree mode x) (GBuildEntrypointsTree mode y)+ GBuildEntrypointsTree _ G.V1 =+ 'EPLeaf GBuildEntrypointsTree EpdPlain (G.C1 _ _) = 'EPLeaf@@ -351,6 +353,13 @@ instance GEntrypointsNotes mode 'EPLeaf G.U1 where type GAllEntrypoints mode 'EPLeaf G.U1 = '[] type GLookupEntrypoint mode 'EPLeaf G.U1 = Fcf.ConstFn 'Nothing+ gMkEntrypointsNotes = (starNotes, noAnn)+ gMkEpLiftSequence _ = EpConstructionFailed+ gMkDescs = RNil++instance GEntrypointsNotes mode 'EPLeaf G.V1 where+ type GAllEntrypoints mode 'EPLeaf G.V1 = '[]+ type GLookupEntrypoint mode 'EPLeaf G.V1 = Fcf.ConstFn 'Nothing gMkEntrypointsNotes = (starNotes, noAnn) gMkEpLiftSequence _ = EpConstructionFailed gMkDescs = RNil
src/Lorentz/Errors.hs view
@@ -49,14 +49,11 @@ , errorTagToMText ) where -import Debug qualified (show)- import Data.Char qualified as C import Data.List qualified as L import Fmt (Buildable, build, fmt, pretty, (+|), (|+)) import Language.Haskell.TH.Syntax (Lift) import Text.Read (readsPrec)-import Text.Show qualified import Lorentz.Base import Lorentz.Doc@@ -257,9 +254,6 @@ instance Buildable SomeError where build (SomeError e) = errorToVal e (build . untypeValue) -instance Show SomeError where- show = pretty- ---------------------------------------------------------------------------- -- General instructions ----------------------------------------------------------------------------@@ -485,11 +479,6 @@ -- Special treatment of no-arg errors ------------------------------------------------------------------------------instance Eq (CustomErrorRep tag) => Eq (() -> CustomError tag) where- e1 == e2 = e1 () == e2 ()-instance Show (CustomErrorRep tag) => Show (() -> CustomError tag) where- show e = Debug.show (e ()) -- | If 'CustomError' constructor is not provided its argument, we assume -- that this is unit-arg error and interpret the passed value as complete.
src/Lorentz/Ext.hs view
@@ -81,7 +81,7 @@ stackType :: forall s. s :-> s stackType = I Nop -_sample1 :: s ~ (a : s') => s :-> s+_sample1 :: (s ~ (a : s')) => s :-> s _sample1 = printComment $ "Head is " <> stackRef @0 _sample2 :: Integer : Natural : s :-> Integer : Natural : s
src/Lorentz/Macro.hs view
@@ -383,11 +383,11 @@ -- of arguments. -- -- Given a stack of 3 elements,--- >>> arg = (1 :: Integer, (2 :: Integer, 3 :: Integer))+-- >>> arg = (1 :: Integer) ::: (2 :: Integer) ::: (3 :: Integer) -- -- @framedN@ will have access to exactly the number of elements specified, -- >>> framedN @1 drop -$ arg--- (2,3)+-- 2 ::: 3 -- >>> framedN @1 (drop # drop) -$ arg -- ... -- ... error:@@ -403,7 +403,8 @@ -- >>> framedN @5 (drop # drop # drop # drop) -$ arg -- ... -- ... error:--- ... Couldn't match type ‘Integer’ with ‘(a0, (a1, out))’+-- ... Couldn't match type ‘Integer’+-- ... with ‘ZippedStackRepr a0 (ZippedStackRepr a1 out)’ -- ... framedN@@ -452,7 +453,7 @@ -- >>> papair == pair # pair -- True ----- >>> papair -$ (True, (1, ()))+-- >>> papair -$ True ::: 1 ::: () -- ((True,1),()) papair :: a : b : c : s :-> ((a, b), c) : s papair = pair # pair@@ -461,7 +462,7 @@ -- >>> ppaiir == dip pair # pair -- True ----- >>> ppaiir -$ (True, (1, ()))+-- >>> ppaiir -$ True ::: 1 ::: () -- (True,(1,())) ppaiir :: a : b : c : s :-> (a, (b, c)) : s ppaiir = dip pair # pair@@ -506,7 +507,7 @@ -- >>> setCar == cdr # swap # pair -- True ----- >>> setCar -$ ((True, 1), ())+-- >>> setCar -$ (True, 1) ::: () -- ((),1) setCar :: (a, b1) : (b2 : s) :-> (b2, b1) : s setCar = cdr # swap # pair@@ -515,7 +516,7 @@ -- >>> setCdr == car # pair -- True ----- >>> setCdr -$ ((True, 1), ())+-- >>> setCdr -$ (True, 1) ::: () -- (True,()) setCdr :: (a, b1) : (b2 : s) :-> (a, b2) : s setCdr = car # pair@@ -573,10 +574,10 @@ -- >>> when_ (push 5 # add @Integer @Integer) == if_ (push 5 # add @Integer @Integer) nop -- True ----- >>> when_ (push 5 # add @Integer) -$ (True, 3)+-- >>> when_ (push 5 # add @Integer) -$ True ::: 3 -- 8 ----- >>> when_ (push 5 # add @Integer) -$ (False, 3)+-- >>> when_ (push 5 # add @Integer) -$ False ::: 3 -- 3 when_ :: (s :-> s) -> (Bool : s :-> s) when_ i = if_ i nop@@ -585,10 +586,10 @@ -- >>> unless_ (push 5 # add @Integer @Integer) == if_ nop (push 5 # add @Integer @Integer) -- True ----- >>> unless_ (push 5 # add @Integer) -$ (True, 3)+-- >>> unless_ (push 5 # add @Integer) -$ True ::: 3 -- 3 ----- >>> unless_ (push 5 # add @Integer) -$ (False, 3)+-- >>> unless_ (push 5 # add @Integer) -$ False ::: 3 -- 8 unless_ :: (s :-> s) -> (Bool : s :-> s) unless_ i = if_ nop i@@ -597,7 +598,7 @@ -- >>> whenSome drop == ifSome drop nop -- True ----- >>> whenSome drop -$ (Just 1 :: Maybe Integer, ())+-- >>> whenSome drop -$ Just 1 ::: () -- () whenSome :: (a : s :-> s) -> (Maybe a : s :-> s) whenSome i = ifSome i nop
src/Lorentz/Run/Simple.hs view
@@ -10,6 +10,8 @@ , (&?-) , (&-) , (<-$>)+ , ZippedStackRepr(..)+ , ZSNil(..) ) where import Lorentz.Base@@ -45,16 +47,19 @@ -- | Like @'-$?'@, assumes that no failure is possible. ----- For testing and demonstration purposes. Note, that here types of variables are specified, because--- the result type of arithmetic operations depends on them.+-- For testing and demonstration purposes. Note, that we specify the result type of polymorphic+-- operations to avoid ambiguity arising from polymorphic literals. --+-- Use 'ZippedStackRepr' to represent stack of two or more elements, and 'ZSNil' for empty stacks.+-- Stacks of one element are represented by the element itself.+-- -- >>> nop -$ 5 -- 5--- >>> sub -$ ((3 :: Integer), (2 :: Integer))+-- >>> sub -$ 3 ::: 2 :: Integer -- 1--- >>> push 9 -$ ()+-- >>> push 9 -$ ZSNil -- 9--- >>> add # add -$ ((1 :: Integer), ((2 :: Integer), (3 :: Integer)))+-- >>> add # add -$ 1 ::: 2 ::: 3 :: Integer -- 6 infixr 2 -$ (-$) :: (ZipInstr inps, IsoValue (ZippedStack inps), IsoValue out, HasCallStack)
src/Lorentz/UParam.hs view
@@ -46,14 +46,11 @@ , unwrapUParam ) where -import Debug qualified (show)- import Data.Constraint ((\\)) import Fcf qualified import Fmt (Buildable(..)) import GHC.Generics ((:*:)(..), (:+:)(..)) import GHC.Generics qualified as G-import Text.Show qualified import Lorentz.ADT import Lorentz.Annotation (HasAnnotation)@@ -165,8 +162,7 @@ data ConstrainedSome (c :: Type -> Constraint) where ConstrainedSome :: c a => a -> ConstrainedSome c -instance Show (ConstrainedSome Show) where- show (ConstrainedSome a) = Debug.show a+deriving stock instance Show (ConstrainedSome Show) instance Buildable (ConstrainedSome Buildable) where build (ConstrainedSome a) = build a
src/Lorentz/Value.hs view
@@ -173,7 +173,7 @@ convertNFixedToFixed (MkNFixed a) = MkFixed (fromIntegral a) instance (HasResolution a) => Show (NFixed a) where- show = show . convertNFixedToFixed+ showsPrec d = Text.Show.showsPrec d . convertNFixedToFixed -- Note: This instances are copies of those in Data.Fixed for Fixed datatype instance (HasResolution a) => Num (NFixed a) where
src/Lorentz/Zip.hs view
@@ -16,6 +16,8 @@ , ZipInstrs , zippingStack , unzippingStack+ , ZippedStackRepr(..)+ , ZSNil(..) ) where import Prelude hiding (drop)@@ -49,6 +51,18 @@ on this module. -} +infixr 5 :::+-- | A type used to represent a zipped stack of at least two elements,+-- isomorphic to a pair and represented as such in Michelson.+data ZippedStackRepr a b = a ::: b+ deriving stock (Show, Eq, Generic)+ deriving anyclass (IsoValue)+-- | A type used to represent an empty zipped stack, isomorphic to a unit and+-- represented as such in Michelson.+data ZSNil = ZSNil+ deriving stock (Show, Eq, Generic)+ deriving anyclass (IsoValue)+ -- | Zipping stack into tuple and back. class (KnownIsoT (ZippedStack s)) => ZipInstr (s :: [Type]) where -- | A type which contains the whole stack zipped.@@ -70,7 +84,7 @@ unzipInstr = I (unzipInstrTyped @s) instance ZipInstr '[] where- type ZippedStack '[] = ()+ type ZippedStack '[] = ZSNil zipInstrTyped = UNIT unzipInstrTyped = DROP @@ -82,7 +96,7 @@ -- | Such definition seems the only possible one we can support -- efficiently. instance (ZipInstr (b ': s), KnownIsoT a) => ZipInstr (a ': b ': s) where- type ZippedStack (a ': b ': s) = (a, ZippedStack (b ': s))+ type ZippedStack (a ': b ': s) = ZippedStackRepr a (ZippedStack (b ': s)) zipInstrTyped = DIP (zipInstrTyped @(b ': s)) `seqOpt` PAIR unzipInstrTyped = UNPAIR `seqOpt` DIP (unzipInstrTyped @(b ': s))