| Safe Haskell | Safe-Inferred |
|---|---|
| Language | Haskell2010 |
PlutusCore.Builtin.Debug
Description
This module helps to visualize and debug the BuiltinMeaning inference machinery from the
Elaborate and Meaning modules.
Synopsis
- elaborateDebug :: forall a j. ElaborateFromTo DefaultUni 0 j (Term TyName Name DefaultUni DefaultFun ()) a => a -> a
- makeBuiltinMeaningDebug :: forall a. MakeBuiltinMeaning a (Term TyName Name DefaultUni DefaultFun ()) => a -> a
- module PlutusCore.Name.Unique
- module PlutusCore.Default
- module PlutusCore.Core
- newtype Opaque val (rep :: Some TyNameRep]) val args res where
- knownPolytype :: TypeScheme val args res
- toPolyF :: ReadKnownM (FoldArgs args res, FoldArgs args ExBudgetStream) -> BuiltinRuntime val
- type family ThrowOnBothEmpty binds args isBuiltin a where ...
- class MakeBuiltinMeaning a val where
- makeBuiltinMeaning :: a -> (cost -> FoldArgs (GetArgs a) ExBudgetStream) -> BuiltinMeaning val cost
- toBuiltinRuntime :: cost -> BuiltinMeaning val cost -> BuiltinRuntime val
- toBuiltinsRuntime :: (cost ~ CostingPart uni fun, ToBuiltinMeaning uni fun, HasMeaningIn uni val) => BuiltinSemanticsVariant fun -> cost -> BuiltinsRuntime fun val
- module PlutusCore.Builtin.Elaborate
Documentation
elaborateDebug :: forall a j. ElaborateFromTo DefaultUni 0 j (Term TyName Name DefaultUni DefaultFun ()) a => a -> a #
Instantiate type variables in the type of a value using ElaborateFromTo. Example usages:
>>>:t elaborateDebug FalseelaborateDebug False :: Bool>>>:t elaborateDebug fstelaborateDebug fst :: (TyVarRep ('TyNameRep "a" 0), TyVarRep ('TyNameRep "b" 1)) -> TyVarRep ('TyNameRep "a" 0)
makeBuiltinMeaningDebug :: forall a. MakeBuiltinMeaning a (Term TyName Name DefaultUni DefaultFun ()) => a -> a #
module PlutusCore.Name.Unique
module PlutusCore.Default
module PlutusCore.Core
newtype Opaque val (rep :: Type) #
The AST of a value with a Plutus type attached to it. The type is for the Plutus type checker
to look at. Opaque can appear in the type of the denotation of a builtin.
Instances
| KnownTypeAst tyname uni rep => KnownTypeAst tyname uni (Opaque val rep :: Some TyNameRep] # | |
| uni ~ UniOf val => MakeKnownIn uni val (Opaque val rep) # | |
Defined in PlutusCore.Builtin.KnownType Methods makeKnown :: Opaque val rep -> BuiltinResult val # | |
| uni ~ UniOf val => ReadKnownIn uni val (Opaque val rep) # | |
Defined in PlutusCore.Builtin.KnownType Methods readKnown :: val -> ReadKnownM (Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Monoid (Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Semigroup (Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Bounded (Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Enum (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods succ :: Opaque val rep -> Opaque val rep # pred :: Opaque val rep -> Opaque val rep # toEnum :: Int -> Opaque val rep # fromEnum :: Opaque val rep -> Int # enumFrom :: Opaque val rep -> [Opaque val rep] # enumFromThen :: Opaque val rep -> Opaque val rep -> [Opaque val rep] # enumFromTo :: Opaque val rep -> Opaque val rep -> [Opaque val rep] # enumFromThenTo :: Opaque val rep -> Opaque val rep -> Opaque val rep -> [Opaque val rep] # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Ix (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods range :: (Opaque val rep, Opaque val rep) -> [Opaque val rep] # index :: (Opaque val rep, Opaque val rep) -> Opaque val rep -> Int # unsafeIndex :: (Opaque val rep, Opaque val rep) -> Opaque val rep -> Int # inRange :: (Opaque val rep, Opaque val rep) -> Opaque val rep -> Bool # rangeSize :: (Opaque val rep, Opaque val rep) -> Int # unsafeRangeSize :: (Opaque val rep, Opaque val rep) -> Int # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Num (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods (+) :: Opaque val rep -> Opaque val rep -> Opaque val rep # (-) :: Opaque val rep -> Opaque val rep -> Opaque val rep # (*) :: Opaque val rep -> Opaque val rep -> Opaque val rep # negate :: Opaque val rep -> Opaque val rep # abs :: Opaque val rep -> Opaque val rep # signum :: Opaque val rep -> Opaque val rep # fromInteger :: Integer -> Opaque val rep # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Integral (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods quot :: Opaque val rep -> Opaque val rep -> Opaque val rep # rem :: Opaque val rep -> Opaque val rep -> Opaque val rep # div :: Opaque val rep -> Opaque val rep -> Opaque val rep # mod :: Opaque val rep -> Opaque val rep -> Opaque val rep # quotRem :: Opaque val rep -> Opaque val rep -> (Opaque val rep, Opaque val rep) # divMod :: Opaque val rep -> Opaque val rep -> (Opaque val rep, Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Real (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods toRational :: Opaque val rep -> Rational # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Eq (Opaque val rep) # | |
| (TypeError NoConstraintsErrMsg :: Constraint) => Ord (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods compare :: Opaque val rep -> Opaque val rep -> Ordering # (<) :: Opaque val rep -> Opaque val rep -> Bool # (<=) :: Opaque val rep -> Opaque val rep -> Bool # (>) :: Opaque val rep -> Opaque val rep -> Bool # (>=) :: Opaque val rep -> Opaque val rep -> Bool # | |
| HasConstant val => HasConstant (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism | |
| ExMemoryUsage val => ExMemoryUsage (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism Methods memoryUsage :: Opaque val rep -> CostRose # | |
| type ToBinds uni acc (Opaque val rep :: Type) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
| type ToHoles uni _1 (Opaque val rep :: Type) # | |
| type IsBuiltin uni (Opaque val rep :: Type) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
| type UniOf (Opaque val rep) # | |
Defined in PlutusCore.Builtin.Polymorphism | |
newtype SomeConstant uni (rep :: Type) #
For unlifting from the Constant constructor when the stored value is of a monomorphic
built-in type
The rep parameter specifies how the type looks on the PLC side (i.e. just like with
Opaque val rep).
Constructors
| SomeConstant | |
Fields
| |
Instances
| KnownTypeAst tyname uni rep => KnownTypeAst tyname uni (SomeConstant uni rep :: Some name) (ToBinds uni acc a) | |
| type ToHoles uni _1 (TyForallRep name a :: Type) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
| type IsBuiltin uni (TyForallRep name a :: Type) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
data family BuiltinHead x #
For annotating an uninstantiated built-in type, so that it gets handled by the right instance or type family.
Instances
| Contains uni f => KnownTypeAst tyname uni (BuiltinHead f :: a) # | |
Defined in PlutusCore.Builtin.KnownTypeAst Associated Types type IsBuiltin uni (BuiltinHead f) :: Some TyNameRep] # | |
| type ToBinds uni acc (BuiltinHead f :: a) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
| type ToHoles uni _1 (BuiltinHead f :: a) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
| type IsBuiltin uni (BuiltinHead f :: a) # | |
Defined in PlutusCore.Builtin.KnownTypeAst | |
LastArg x y is the same thing as y in the signature of the denotation of a built-in
functions and this type is only used for referencing x before y, so that the elaboration
machinery generates x before y in the all part of the Plutus signature of the builtin.
This is a very hacky and indirect way of specifying the ordering of type variables in a Plutus
signature, in future we'll do it explicitly by introducing a Forall binder for use in type
signatures of denotations of builtins.
type family ElaborateBuiltin uni x #
Take an iterated application of a built-in type and elaborate every function application
inside of it to TyAppRep and annotate the head with BuiltinHead.
The idea is that we don't need to process built-in types manually if we simply add some
annotations for instance resolution to look for. Think what we'd have to do manually for, say,
ToHoles: traverse the spine of the application and collect all the holes into a list, which is
troubling, because type applications are left-nested and lists are right-nested, so we'd have to
use accumulators or an explicit Reverse type family. And then we also have KnownTypeAst and
ToBinds, so handling built-in types in a special way for each of those would be a hassle,
especially given the fact that type-level Haskell is not exactly good at computing things.
With the ElaborateBuiltin approach we get KnownTypeAst, ToHoles and ToBinds for free.
We make this an open type family, so that elaboration is customizable for each universe.
Instances
| type ElaborateBuiltin DefaultUni (x :: a) # | |
Defined in PlutusCore.Default.Universe | |
type family AllElaboratedArgs constr x where ... #
Take a constraint and use it to constrain every argument of a possibly 0-ary elaborated application of a built-in type.
Equations
| AllElaboratedArgs constr (f `TyAppRep` x) = (constr x, AllElaboratedArgs constr f) | |
| AllElaboratedArgs _ (BuiltinHead _) = () |
class AllElaboratedArgs constr (ElaborateBuiltin uni x) => AllBuiltinArgs uni constr x #
Take a constraint and use it to constrain every argument of a possibly 0-ary application of a built-in type.
Instances
| AllElaboratedArgs constr (ElaborateBuiltin uni x) => AllBuiltinArgs uni constr (x :: a) # | |
Defined in PlutusCore.Builtin.Polymorphism | |
type family FoldArgs args res where ... #
Turn a list of Haskell types args into a functional type ending in res.
>>>:set -XDataKinds>>>:kind! FoldArgs [(), Bool] IntegerFoldArgs [(), Bool] Integer :: * = () -> Bool -> Integer
data BuiltinMeaning val cost #
The meaning of a built-in function consists of its type represented as a TypeScheme,
its Haskell denotation and its uninstantiated runtime denotation.
The TypeScheme of a built-in function is used for example for
- computing the PLC type of the function to be used during type checking
- getting arity information
- generating arbitrary values to apply the function to in tests
The denotation is lazy, so that we don't need to worry about a builtin being bottom (happens in tests). The production path is not affected by that, since only runtime denotations are used for evaluation.
Constructors
| forall args res. BuiltinMeaning (TypeScheme val args res) ~(FoldArgs args res) (cost -> BuiltinRuntime val) |
type HasMeaningIn uni val = (Typeable val, ExMemoryUsage val, HasConstantIn uni val) #
Constraints available when defining a built-in function.
class (Typeable uni, Typeable fun, Bounded fun, Enum fun, Ix fun, Default (BuiltinSemanticsVariant fun)) => ToBuiltinMeaning uni fun where #
A type class for "each function from a set of built-in functions has a BuiltinMeaning".
Associated Types
type CostingPart uni fun #
The cost part of BuiltinMeaning.
data BuiltinSemanticsVariant fun #
See Note [Builtin semantics variants]
Methods
toBuiltinMeaning :: HasMeaningIn uni val => BuiltinSemanticsVariant fun -> fun -> BuiltinMeaning val (CostingPart uni fun) #
Get the BuiltinMeaning of a built-in function.
Instances
withTypeSchemeOfBuiltinFunction :: forall val fun r. (ToBuiltinMeaning (UniOf val) fun, ExMemoryUsage val, Typeable val, HasConstant val) => BuiltinSemanticsVariant fun -> fun -> (forall args res. TypeScheme val args res -> r) -> r #
Feed the TypeScheme of the given built-in function to the continuation.
typeOfBuiltinFunction :: forall uni fun. ToBuiltinMeaning uni fun => BuiltinSemanticsVariant fun -> fun -> Type TyName uni () #
Get the type of a built-in function.
class KnownMonotype val args res where #
A class that allows us to derive a monotype for a builtin.
We could've computed the runtime denotation from the
TypeScheme and the denotation of the builtin, but not statically (due to unfolding not working
for recursive functions and TypeScheme being recursive, i.e. requiring the conversion function
to be recursive), and so it would cause us to retain a lot of evaluation-irrelevant stuff in the
constructors of BuiltinRuntime, which has to make evaluation slower (we didn't check) and
certainly makes the generated Core much harder to read. Technically speaking, we could get
a RuntimeScheme from the TypeScheme and the denotation statically if we changed the
definition of TypeScheme and made it a singleton, but then the conversion function would have
to become a class anyway and we'd just replicate what we have here, except in a much more
complicated way.
Methods
knownMonotype :: TypeScheme val args res #
toMonoF :: ReadKnownM (FoldArgs args res, FoldArgs args ExBudgetStream) -> BuiltinRuntime val #
Convert the denotation of a builtin to its runtime counterpart.
The argument is in ReadKnownM, because that's what deferred unlifting amounts to:
passing the action returning the builtin application around until full saturation, which is
when the action actually gets run.
Instances
| (Typeable res, KnownTypeAst TyName (UniOf val) res, MakeKnown val res) => KnownMonotype val ('[] :: [Type]) res # | Once we've run out of term-level arguments, we return a
|
Defined in PlutusCore.Builtin.Meaning Methods knownMonotype :: TypeScheme val '[] res # toMonoF :: ReadKnownM (FoldArgs '[] res, FoldArgs '[] ExBudgetStream) -> BuiltinRuntime val # | |
| (Typeable arg, KnownTypeAst TyName (UniOf val) arg, MakeKnown val arg, ReadKnown val arg, KnownMonotype val args res) => KnownMonotype val (arg ': args) res # | Every term-level argument becomes a |
Defined in PlutusCore.Builtin.Meaning Methods knownMonotype :: TypeScheme val (arg ': args) res # toMonoF :: ReadKnownM (FoldArgs (arg ': args) res, FoldArgs (arg ': args) ExBudgetStream) -> BuiltinRuntime val # | |
class KnownMonotype val args res => KnownPolytype (binds :: [Some TyNameRep]) val args res where #
A class that allows us to derive a polytype for a builtin.
Methods
knownPolytype :: TypeScheme val args res #
toPolyF :: ReadKnownM (FoldArgs args res, FoldArgs args ExBudgetStream) -> BuiltinRuntime val #
Convert the denotation of a builtin to its runtime counterpart.
The argument is in ReadKnownM, because that's what we need to do:
passing the action returning the builtin application around until full saturation, which is
when the action actually gets run.
Instances
| KnownMonotype val args res => KnownPolytype ('[] :: [Some ('TyNameRep name uniq :: TyNameRep kind) ': binds) val args res # | Every type-level argument becomes a |
Defined in PlutusCore.Builtin.Meaning Methods knownPolytype :: TypeScheme val args res # toPolyF :: ReadKnownM (FoldArgs args res, FoldArgs args ExBudgetStream) -> BuiltinRuntime val # | |
type family ThrowOnBothEmpty binds args isBuiltin a where ... #
Ensure a built-in function is not nullary and throw a nice error otherwise.
Equations
| ThrowOnBothEmpty '[] '[] 'True a = TypeError (('Text "A built-in function must take at least one type or term argument" ':$$: ((('Text "\8216" ':<>: 'ShowType a) ':<>: 'Text "\8217 is a built-in type") ':<>: 'Text " so you can embed any of its values as a constant")) ':$$: 'Text "If you still want a built-in function, add a dummy \8216()\8217 argument") | |
| ThrowOnBothEmpty '[] '[] 'False a = TypeError ('Text "A built-in function must take at least one type or term argument" ':$$: 'Text "To fix this error add a dummy \8216()\8217 argument") | |
| ThrowOnBothEmpty _ _ _ _ = () |
class MakeBuiltinMeaning a val where #
A function turned into a type class with exactly one fully general instance.
We can't package up the constraints of makeBuiltinMeaning (see the instance) into a type or
class synonym, because they contain a bunch of variables defined by ~ or determined via
functional dependencies and neither class nor type definitions can handle that
(see https://gitlab.haskell.org/ghc/ghc/-/issues/7100). Inlining three lines of constraints
whenever we need to call makeBuiltinMeaning over a non-concrete type is a bad option and this
abstraction is free anyway, hence its existence.
The a type variable goes first, because makeBuiltinMeaning @A is a common pattern.
Methods
makeBuiltinMeaning :: a -> (cost -> FoldArgs (GetArgs a) ExBudgetStream) -> BuiltinMeaning val cost #
Construct the meaning for a built-in function by automatically deriving its
TypeScheme, given
- the denotation of the builtin
- an uninstantiated costing function
Instances
| (uni Some TyNameRep]) a, args ~ GetArgs a, a ~ FoldArgs args res, ThrowOnBothEmpty binds args (IsBuiltin uni a) a, ElaborateFromTo uni 0 j val a, KnownPolytype binds val args res) => MakeBuiltinMeaning a val # | |
Defined in PlutusCore.Builtin.Meaning Methods makeBuiltinMeaning :: a -> (cost -> FoldArgs (GetArgs a) ExBudgetStream) -> BuiltinMeaning val cost # | |
toBuiltinRuntime :: cost -> BuiltinMeaning val cost -> BuiltinRuntime val #
Convert a BuiltinMeaning to a BuiltinRuntime given a cost model.
toBuiltinsRuntime :: (cost ~ CostingPart uni fun, ToBuiltinMeaning uni fun, HasMeaningIn uni val) => BuiltinSemanticsVariant fun -> cost -> BuiltinsRuntime fun val #
Calculate runtime info for all built-in functions given meanings of builtins (as a constraint), the semantics variant of the set of builtins and a cost model.
module PlutusCore.Builtin.Elaborate