Safe Haskell | None |
---|---|
Language | Haskell2010 |
Entrypoints utilities for Lorentz
Synopsis
- class EntryPointsDerivation deriv cp where
- type EpdAllEntryPoints deriv cp :: [(Symbol, Type)]
- type EpdLookupEntryPoint deriv cp :: Symbol -> Exp (Maybe Type)
- epdNotes :: Notes (ToT cp)
- epdCall :: (KnownSymbol name, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntryPoint deriv cp name))
- class (EntryPointsDerivation (ParameterEntryPointsDerivation cp) cp, RequireAllUniqueEntryPoints (ParameterEntryPointsDerivation cp) cp) => ParameterHasEntryPoints cp where
- type ParameterEntryPointsDerivation cp :: Type
- type ParameterDeclaresEntryPoints cp = (If (CanHaveEntryPoints cp) (ParameterHasEntryPoints cp) (() :: Constraint), NiceParameter cp, EntryPointsDerivation (GetParameterEpDerivation cp) cp)
- type family AllParameterEntryPoints (cp :: Type) :: [(Symbol, Type)] where ...
- type family LookupParameterEntryPoint (cp :: Type) (name :: Symbol) :: Exp (Maybe Type) where ...
- parameterEntryPointsToNotes :: forall cp. ParameterDeclaresEntryPoints cp => ParamNotes (ToT cp)
- flattenEntryPoints :: SingI t => ParamNotes t -> Map EpName Type
- type GetEntryPointArg cp name = Eval (LiftM2 FromMaybe (TError ((Text "Entrypoint not found: " :<>: ShowType name) :$$: ((Text "In contract parameter `" :<>: ShowType cp) :<>: Text "`"))) (LookupParameterEntryPoint cp name))
- parameterEntryPointCall :: forall cp name. (ParameterDeclaresEntryPoints cp, KnownSymbol name) => Label name -> EntryPointCall cp (GetEntryPointArg cp name)
- type GetDefaultEntryPointArg cp = Eval (LiftM2 FromMaybe (Pure cp) (LookupParameterEntryPoint cp DefaultEpName))
- parameterEntryPointCallDefault :: forall cp. ParameterDeclaresEntryPoints cp => EntryPointCall cp (GetDefaultEntryPointArg cp)
- type NoExplicitDefaultEntryPoint cp = Eval (LiftM3 UnMaybe (Pure (Pure (() :: Constraint))) (TError (Text "Parameter used here must have no explicit \"default\" entrypoint" :$$: ((Text "In parameter type `" :<>: ShowType cp) :<>: Text "`"))) (LookupParameterEntryPoint cp DefaultEpName))
- data EntryPointRef (mname :: Maybe Symbol) where
- CallDefault :: EntryPointRef Nothing
- Call :: (KnownSymbol name, ForbidDefaultName name) => EntryPointRef (Just name)
- eprName :: forall mname. EntryPointRef mname -> EpName
- type family GetEntryPointArgCustom cp mname :: Type where ...
- class HasEntryPointArg cp name arg where
- useHasEntryPointArg :: name -> (Dict (ParameterScope (ToT arg)), EpName)
- type HasDefEntryPointArg cp defEpName defArg = (defEpName ~ EntryPointRef Nothing, HasEntryPointArg cp defEpName defArg)
- newtype TrustEpName = TrustEpName EpName
- parameterEntryPointCallCustom :: forall cp mname. ParameterDeclaresEntryPoints cp => EntryPointRef mname -> EntryPointCall cp (GetEntryPointArgCustom cp mname)
- newtype ParameterWrapper (deriv :: Type) cp = ParameterWrapper {
- unParameterWraper :: cp
- data EpdNone
- data EpdPlain
- data EpdRecursive
Typeclasses
class EntryPointsDerivation deriv cp where Source #
Defines a generalized way to declare entrypoints for various parameter types.
When defining instances of this typeclass, set concrete deriv
argument
and leave variable cp
argument.
Also keep in mind, that in presence of explicit default entrypoint, all other
Or
arms should be callable.
type EpdAllEntryPoints deriv cp :: [(Symbol, Type)] Source #
Name and argument of each entrypoint. This may include intermediate ones, even root if necessary.
Touching this type family is costly (O(N^2)
), don't use it often.
type EpdLookupEntryPoint deriv cp :: Symbol -> Exp (Maybe Type) Source #
Get entrypoint argument by name.
epdNotes :: Notes (ToT cp) Source #
Construct parameter annotations corresponding to expected entrypoints set.
This method is implementation detail, for actual notes construction
use parameterEntryPointsToNotes
.
epdCall :: (KnownSymbol name, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntryPoint deriv cp name)) Source #
Construct entrypoint caller.
This does not treat calls to default entrypoint in a special way.
This method is implementation detail, for actual entrypoint lookup
use parameterEntryPointCall
.
Instances
class (EntryPointsDerivation (ParameterEntryPointsDerivation cp) cp, RequireAllUniqueEntryPoints (ParameterEntryPointsDerivation cp) cp) => ParameterHasEntryPoints cp Source #
Which entrypoints given parameter declares.
Note that usually this function should not be used as constraint, use
ParameterDeclaresEntryPoints
for this purpose.
type ParameterEntryPointsDerivation cp :: Type Source #
Instances
(NiceParameter cp, EntryPointsDerivation epd cp, RequireAllUniqueEntryPoints epd cp) => ParameterHasEntryPoints (ParameterWrapper epd cp) Source # | |
Defined in Lorentz.EntryPoints.Manual type ParameterEntryPointsDerivation (ParameterWrapper epd cp) :: Type Source # |
type ParameterDeclaresEntryPoints cp = (If (CanHaveEntryPoints cp) (ParameterHasEntryPoints cp) (() :: Constraint), NiceParameter cp, EntryPointsDerivation (GetParameterEpDerivation cp) cp) Source #
Parameter declares some entrypoints.
This is a version of ParameterHasEntryPoints
which we actually use in
constraints. When given type is a sum type or newtype, we refer to
ParameterHasEntryPoints
instance, otherwise this instance is not
necessary.
Entrypoints API
type family AllParameterEntryPoints (cp :: Type) :: [(Symbol, Type)] where ... Source #
Get all entrypoints declared for parameter.
AllParameterEntryPoints cp = EpdAllEntryPoints (GetParameterEpDerivation cp) cp |
type family LookupParameterEntryPoint (cp :: Type) (name :: Symbol) :: Exp (Maybe Type) where ... Source #
Lookup for entrypoint type by name.
Does not treat default entrypoints in a special way.
LookupParameterEntryPoint cp name = EpdLookupEntryPoint (GetParameterEpDerivation cp) cp name |
parameterEntryPointsToNotes :: forall cp. ParameterDeclaresEntryPoints cp => ParamNotes (ToT cp) Source #
Derive annotations for given parameter.
flattenEntryPoints :: SingI t => ParamNotes t -> Map EpName Type Source #
Flatten a provided list of notes to a map of its entrypoints and its corresponding utype.
It is obtained by constructing `insert k1 v1 (insert k2 v2 ... mempty)`
pipe using Endo
so that it is more concise rather than stacking composition
of monoidal endomorphisms explicitly. Note that here no duplicates can appear
in returned map for ParamNotes
even if they may appear inside passed Notes
tree.
type GetEntryPointArg cp name = Eval (LiftM2 FromMaybe (TError ((Text "Entrypoint not found: " :<>: ShowType name) :$$: ((Text "In contract parameter `" :<>: ShowType cp) :<>: Text "`"))) (LookupParameterEntryPoint cp name)) Source #
Get type of entrypoint with given name, fail if not found.
parameterEntryPointCall :: forall cp name. (ParameterDeclaresEntryPoints cp, KnownSymbol name) => Label name -> EntryPointCall cp (GetEntryPointArg cp name) Source #
Prepare call to given entrypoint.
This does not treat calls to default entrypoint in a special way.
To call default entrypoint properly use parameterEntryPointCallDefault
.
type GetDefaultEntryPointArg cp = Eval (LiftM2 FromMaybe (Pure cp) (LookupParameterEntryPoint cp DefaultEpName)) Source #
Get type of entrypoint with given name, fail if not found.
parameterEntryPointCallDefault :: forall cp. ParameterDeclaresEntryPoints cp => EntryPointCall cp (GetDefaultEntryPointArg cp) Source #
Call the default entrypoint.
type NoExplicitDefaultEntryPoint cp = Eval (LiftM3 UnMaybe (Pure (Pure (() :: Constraint))) (TError (Text "Parameter used here must have no explicit \"default\" entrypoint" :$$: ((Text "In parameter type `" :<>: ShowType cp) :<>: Text "`"))) (LookupParameterEntryPoint cp DefaultEpName)) Source #
Ensure that there is no explicit "default" entrypoint.
data EntryPointRef (mname :: Maybe Symbol) where Source #
Which entrypoint to call.
We intentionally distinguish default and non-default cases because this makes API more details-agnostic.
CallDefault :: EntryPointRef Nothing | Call the default entrypoint, or root if no explicit default is assigned. |
Call :: (KnownSymbol name, ForbidDefaultName name) => EntryPointRef (Just name) | Call the given entrypoint; calling default is not treated specially. You have to provide entrypoint name via passing it as type argument. Unfortunatelly, here we cannot accept a label because in most cases our entrypoints begin from capital letter (being derived from constructor name), while labels must start from a lower-case letter, and there is no way to make a conversion at type-level. |
Instances
(GetEntryPointArgCustom cp mname ~ arg, ParameterDeclaresEntryPoints cp) => HasEntryPointArg (cp :: Type) (EntryPointRef mname) arg Source # | |
Defined in Lorentz.EntryPoints.Core useHasEntryPointArg :: EntryPointRef mname -> (Dict (ParameterScope (ToT arg)), EpName) Source # |
eprName :: forall mname. EntryPointRef mname -> EpName Source #
type family GetEntryPointArgCustom cp mname :: Type where ... Source #
Universal entrypoint lookup.
GetEntryPointArgCustom cp Nothing = GetDefaultEntryPointArg cp | |
GetEntryPointArgCustom cp (Just name) = GetEntryPointArg cp name |
class HasEntryPointArg cp name arg where Source #
When we call a Lorentz contract we should pass entrypoint name
and corresponding argument. Ideally we want to statically check
that parameter has entrypoint with given name and
argument. Constraint defined by this type class holds for contract
with parameter cp
that have entrypoint matching name
with type
arg
.
In order to check this property statically, we need to know entrypoint
name in compile time, EntryPointRef
type serves this purpose.
If entrypoint name is not known, one can use TrustEpName
wrapper
to take responsibility for presence of this entrypoint.
If you want to call a function which has this constraint, you have
two options:
1. Pass contract parameter cp
using type application, pass EntryPointRef
as a value and pass entrypoint argument. Type system will check that
cp
has an entrypoint with given reference and type.
2. Pass EpName
wrapped into TrustEpName
and entrypoint argument.
In this case passing contract parameter is not necessary, you do not even
have to know it.
useHasEntryPointArg :: name -> (Dict (ParameterScope (ToT arg)), EpName) Source #
Data returned by this method may look somewhat arbitrary.
EpName
is obviously needed because name
can be
EntryPointRef
or TrustEpName
. Dict
is returned because in
EntryPointRef
case we get this evidence for free and don't want
to use it. We seem to always need it anyway.
Instances
NiceParameter arg => HasEntryPointArg (cp :: k) TrustEpName arg Source # | |
Defined in Lorentz.EntryPoints.Core useHasEntryPointArg :: TrustEpName -> (Dict (ParameterScope (ToT arg)), EpName) Source # | |
(GetEntryPointArgCustom cp mname ~ arg, ParameterDeclaresEntryPoints cp) => HasEntryPointArg (cp :: Type) (EntryPointRef mname) arg Source # | |
Defined in Lorentz.EntryPoints.Core useHasEntryPointArg :: EntryPointRef mname -> (Dict (ParameterScope (ToT arg)), EpName) Source # |
type HasDefEntryPointArg cp defEpName defArg = (defEpName ~ EntryPointRef Nothing, HasEntryPointArg cp defEpName defArg) Source #
HasEntryPointArg
constraint specialized to default entrypoint.
newtype TrustEpName Source #
This wrapper allows to pass untyped EpName
and bypass checking
that entrypoint with given name and type exists.
Instances
NiceParameter arg => HasEntryPointArg (cp :: k) TrustEpName arg Source # | |
Defined in Lorentz.EntryPoints.Core useHasEntryPointArg :: TrustEpName -> (Dict (ParameterScope (ToT arg)), EpName) Source # |
parameterEntryPointCallCustom :: forall cp mname. ParameterDeclaresEntryPoints cp => EntryPointRef mname -> EntryPointCall cp (GetEntryPointArgCustom cp mname) Source #
Universal entrypoint calling.
Implementations
newtype ParameterWrapper (deriv :: Type) cp Source #
Wrap parameter into this to locally assign a way to derive entrypoints for it.
Instances
No entrypoints declared, parameter type will serve as argument type of the only existing entrypoint (default one).
Instances
SingI (ToT cp) => EntryPointsDerivation EpdNone cp Source # | |
Defined in Lorentz.EntryPoints.Core type EpdAllEntryPoints EpdNone cp :: [(Symbol, Type)] Source # type EpdLookupEntryPoint EpdNone cp :: Symbol -> Exp (Maybe Type) Source # epdNotes :: Notes (ToT cp) Source # epdCall :: (KnownSymbol name, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntryPoint EpdNone cp name)) Source # | |
type EpdAllEntryPoints EpdNone cp Source # | |
Defined in Lorentz.EntryPoints.Core | |
type EpdLookupEntryPoint EpdNone cp Source # | |
Implementation of ParameterHasEntryPoints
which fits for case when
your contract exposes multiple entrypoints via having sum type as its
parameter.
In particular, each constructor would produce a homonymous entrypoint with
argument type equal to type of constructor field (each constructor should
have only one field).
Constructor called Default
will designate the default entrypoint.
Instances
PlainEntryPointsC False cp => EntryPointsDerivation EpdPlain cp Source # | |
Defined in Lorentz.EntryPoints.Impl type EpdAllEntryPoints EpdPlain cp :: [(Symbol, Type)] Source # type EpdLookupEntryPoint EpdPlain cp :: Symbol -> Exp (Maybe Type) Source # epdNotes :: Notes (ToT cp) Source # epdCall :: (KnownSymbol name, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntryPoint EpdPlain cp name)) Source # | |
type EpdAllEntryPoints EpdPlain cp Source # | |
Defined in Lorentz.EntryPoints.Impl | |
type EpdLookupEntryPoint EpdPlain cp Source # | |
Defined in Lorentz.EntryPoints.Impl |
data EpdRecursive Source #
Similar to EpdPlain
, but for case of parameter being defined as
several nested datatypes.
In particular, this will traverse sum types recursively, stopping at
Michelson primitives (like Natural
) and constructors with number of
fields different from one.
It does not assign names to intermediate nodes of Or
tree, only to the very
leaves.
Instances
PlainEntryPointsC True cp => EntryPointsDerivation EpdRecursive cp Source # | |
Defined in Lorentz.EntryPoints.Impl type EpdAllEntryPoints EpdRecursive cp :: [(Symbol, Type)] Source # type EpdLookupEntryPoint EpdRecursive cp :: Symbol -> Exp (Maybe Type) Source # epdNotes :: Notes (ToT cp) Source # epdCall :: (KnownSymbol name, ParameterScope (ToT cp)) => Label name -> EpConstructionRes (ToT cp) (Eval (EpdLookupEntryPoint EpdRecursive cp name)) Source # | |
type EpdAllEntryPoints EpdRecursive cp Source # | |
Defined in Lorentz.EntryPoints.Impl | |
type EpdLookupEntryPoint EpdRecursive cp Source # | |
Defined in Lorentz.EntryPoints.Impl |