covenant
Copyright(C) MLabs 2025
LicenseApache 2.0
Maintainerkoz@mlabs.city, sean@mlabs.city
Safe HaskellNone
LanguageHaskell2010

Covenant.ASG

Description

The Covenant ASG, and ways to programmatically build it.

Note

We use the term 'ASG' to refer to 'abstract syntax graph'. This is because Covenant uses hash consing to ensure duplicate nodes do not exist, thus producing a DAG structure, rather than a tree.

Since: 1.0.0

Synopsis

The ASG itself

Types

data ASG Source #

A fully-assembled Covenant ASG.

Since: 1.0.0

Instances

Instances details
Show ASG Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

showsPrec :: Int -> ASG -> ShowS #

show :: ASG -> String #

showList :: [ASG] -> ShowS #

Eq ASG Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

(==) :: ASG -> ASG -> Bool #

(/=) :: ASG -> ASG -> Bool #

Functions

topLevelNode :: ASG -> ASGNode Source #

Retrieves the top-level node of an ASG.

Since: 1.0.0

nodeAt :: Id -> ASG -> ASGNode Source #

Given an Id and an ASG, produces the node corresponding to that Id.

Important note

This is only safe to use if the Id comes from a node in the argument ASG. Ids valid in one ASG are not likely to be valid in another. 'Mixing and matching' Ids from different ASGs will at best produce unexpected results, and at worst will crash. You have been warned.

Since: 1.0.0

ASG components

Types

data Id Source #

A unique identifier for a node in a Covenant program.

Since: 1.0.0

Instances

Instances details
Bounded Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

minBound :: Id #

maxBound :: Id #

Enum Id Source #

Needed for internal reasons, even though this type class is terrible.

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

succ :: Id -> Id #

pred :: Id -> Id #

toEnum :: Int -> Id #

fromEnum :: Id -> Int #

enumFrom :: Id -> [Id] #

enumFromThen :: Id -> Id -> [Id] #

enumFromTo :: Id -> Id -> [Id] #

enumFromThenTo :: Id -> Id -> Id -> [Id] #

Show Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Id -> ShowS #

show :: Id -> String #

showList :: [Id] -> ShowS #

Eq Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Id -> Id -> Bool #

(/=) :: Id -> Id -> Bool #

Ord Id Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Id -> Id -> Ordering #

(<) :: Id -> Id -> Bool #

(<=) :: Id -> Id -> Bool #

(>) :: Id -> Id -> Bool #

(>=) :: Id -> Id -> Bool #

max :: Id -> Id -> Id #

min :: Id -> Id -> Id #

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadHashCons Id ASGNode DebugASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.Test

data Ref Source #

A general reference in a Covenant program.

Since: 1.0.0

Constructors

AnArg Arg

A function argument.

Since: 1.0.0

AnId Id

A link to an ASG node.

Since: 1.0.0

Instances

Instances details
Show Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Ref -> ShowS #

show :: Ref -> String #

showList :: [Ref] -> ShowS #

Eq Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Ref -> Ref -> Bool #

(/=) :: Ref -> Ref -> Bool #

Ord Ref Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Ref -> Ref -> Ordering #

(<) :: Ref -> Ref -> Bool #

(<=) :: Ref -> Ref -> Bool #

(>) :: Ref -> Ref -> Bool #

(>=) :: Ref -> Ref -> Bool #

max :: Ref -> Ref -> Ref #

min :: Ref -> Ref -> Ref #

data Arg Source #

An argument passed to a function in a Covenant program.

Since: 1.0.0

Instances

Instances details
Show Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

showsPrec :: Int -> Arg -> ShowS #

show :: Arg -> String #

showList :: [Arg] -> ShowS #

Eq Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: Arg -> Arg -> Bool #

(/=) :: Arg -> Arg -> Bool #

Ord Arg Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

compare :: Arg -> Arg -> Ordering #

(<) :: Arg -> Arg -> Bool #

(<=) :: Arg -> Arg -> Bool #

(>) :: Arg -> Arg -> Bool #

(>=) :: Arg -> Arg -> Bool #

max :: Arg -> Arg -> Arg #

min :: Arg -> Arg -> Arg #

data CompNodeInfo where Source #

Computation-term-specific node information.

Since: 1.0.0

Bundled Patterns

pattern Builtin1 :: OneArgFunc -> CompNodeInfo

A Plutus primop with one argument.

Since: 1.0.0

pattern Builtin2 :: TwoArgFunc -> CompNodeInfo

A Plutus primop with two arguments.

Since: 1.0.0

pattern Builtin3 :: ThreeArgFunc -> CompNodeInfo

A Plutus primop with three arguments.

Since: 1.0.0

pattern Builtin6 :: SixArgFunc -> CompNodeInfo

A Plutus primop with six arguments.

Since: 1.1.0

pattern Lam :: Ref -> CompNodeInfo

A lambda.

Since: 1.2.0

pattern Force :: Ref -> CompNodeInfo

Force a thunk back into the computation it wraps.

Since: 1.0.0

data ValNodeInfo where Source #

Value-term-specific node information.

Since: 1.0.0

Bundled Patterns

pattern Lit :: AConstant -> ValNodeInfo

A compile-time literal of a flat builtin type.

Since: 1.0.0

pattern App :: Id -> Vector Ref -> ValNodeInfo

An application of a computation (the Id field) to some arguments (the Vector field).

Since: 1.0.0

pattern Thunk :: Id -> ValNodeInfo

Wrap a computation into a value (essentially delaying it).

Since: 1.0.0

pattern Cata :: Ref -> Ref -> ValNodeInfo

'Tear down' a self-recursive value with an algebra.

Since: 1.0.0

pattern DataConstructor :: TyName -> ConstructorName -> Vector Ref -> ValNodeInfo

Inject (zero or more) fields into a data constructor

Since: 1.2.0

pattern Match :: Ref -> Vector Ref -> ValNodeInfo

Deconstruct a value of a data type using the supplied handlers for each arm

Since: 1.2.0

data ASGNode Source #

A single node in a Covenant ASG. Where appropriate, these carry their types.

Since: 1.0.0

Constructors

ACompNode (CompT AbstractTy) CompNodeInfo

A computation-typed node.

Since: 1.0.0

AValNode (ValT AbstractTy) ValNodeInfo

A value-typed node

Since: 1.0.0

AnError

An error node.

Since: 1.0.0

Instances

Instances details
Show ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Eq ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

Methods

(==) :: ASGNode -> ASGNode -> Bool #

(/=) :: ASGNode -> ASGNode -> Bool #

Ord ASGNode Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Term

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadHashCons Id ASGNode DebugASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.Test

data ASGNodeType Source #

Helper data type representing the type of any ASG node whatsoever.

Since: 1.0.0

Functions

typeASGNode :: ASGNode -> ASGNodeType Source #

Produces the type of any ASG node.

Since: 1.0.0

ASG builder

Types

data CovenantError Source #

Any problem that might arise when building an ASG programmatically.

Since: 1.0.0

Constructors

TypeError (Bimap Id ASGNode) CovenantTypeError

There was a type error when assembling the ASG. This provides the hash-consed state up to the point of the error.

Since: 1.0.0

EmptyASG

We tried to generate an ASG with no nodes in it.

Since: 1.0.0

TopLevelError

We tried to generate as ASG whose top-level node is an error.

Since: 1.0.0

TopLevelValue (Bimap Id ASGNode) (ValT AbstractTy) ValNodeInfo

We tried to generate an ASG whose top-level node is a value.

Since: 1.0.0

Instances

Instances details
Show CovenantError Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Eq CovenantError Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

newtype ScopeInfo Source #

A tracker for scope-related information while building an ASG programmatically. Currently only tracks available arguments.

Important note

This is a fairly low-level type, designed specifically for ASG construction. While you can do arbitrary things with it, changing things in it outside of the functionality provided by this module is not recommended, unless you know exactly what you're doing.

Since: 1.2.0

Instances

Instances details
Show ScopeInfo Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Eq ScopeInfo Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

(k ~ A_Lens, a ~ Vector (Word32, Vector (ValT AbstractTy)), b ~ Vector (Word32, Vector (ValT AbstractTy))) => LabelOptic "argumentInfo" k ScopeInfo ScopeInfo a b Source #

Gives access to the argument information for the current, and all enclosing, scopes. The 'outer' Vector is a stack of scopes, with lower indexes corresponding to closer scopes: index 0 is our scope, 1 is our enclosing scope, 2 is the enclosing scope of our enclosing scope, etc. The 'inner' Vectors are positional lists of argument types.

Since: 1.2.0

Instance details

Defined in Covenant.ASG

data ASGBuilder a Source #

A concrete monadic stack, providing the minimum amount of functionality needed to build an ASG using the combinators given in this module.

Since: 1.0.0

Instances

Instances details
Applicative ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

pure :: a -> ASGBuilder a #

(<*>) :: ASGBuilder (a -> b) -> ASGBuilder a -> ASGBuilder b #

liftA2 :: (a -> b -> c) -> ASGBuilder a -> ASGBuilder b -> ASGBuilder c #

(*>) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder b #

(<*) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder a #

Functor ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

fmap :: (a -> b) -> ASGBuilder a -> ASGBuilder b #

(<$) :: a -> ASGBuilder b -> ASGBuilder a #

Monad ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

Methods

(>>=) :: ASGBuilder a -> (a -> ASGBuilder b) -> ASGBuilder b #

(>>) :: ASGBuilder a -> ASGBuilder b -> ASGBuilder b #

return :: a -> ASGBuilder a #

MonadError CovenantTypeError ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

MonadReader ASGEnv ASGBuilder Source #

Since: 1.1.0

Instance details

Defined in Covenant.ASG

Methods

ask :: ASGBuilder ASGEnv #

local :: (ASGEnv -> ASGEnv) -> ASGBuilder a -> ASGBuilder a #

reader :: (ASGEnv -> a) -> ASGBuilder a #

MonadHashCons Id ASGNode ASGBuilder Source #

Since: 1.0.0

Instance details

Defined in Covenant.ASG

data TypeAppError Source #

Possible errors resulting from applications of arguments to functions.

Since: 1.0.0

Constructors

LeakingUnifiable (Index "tyvar")

The final type after all arguments are applied is forall a . a.

LeakingWildcard Word64 Int (Index "tyvar")

A wildcard (thus, a skolem) escaped its scope.

ExcessArgs (CompT Renamed) (Vector (Maybe (ValT Renamed)))

We were given too many arguments.

InsufficientArgs Int (CompT Renamed) [Maybe (ValT Renamed)]

We weren't given enough arguments.

Since: 1.1.0

DoesNotUnify (ValT Renamed) (ValT Renamed)

The expected type (first field) and actual type (second field) do not unify.

NoDatatypeInfo TyName

No datatype info associated with requested TyName

Since: 1.1.0

NoBBForm TyName

No BB form. The only datatypes which should lack one are those isomorphic to Void.

Since: 1.1.0

DatatypeInfoRenameFailed TyName RenameError

Datatype renaming failed.

Since: 1.1.0

ImpossibleHappened Text

Something happened that definitely should not have. For right now, this means: The BB form of a datatype isn't a thunk (but it might be useful to keep this around as a catchall for things that really shouldn't happen).

Since: 1.1.0

Instances

Instances details
Show TypeAppError Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Unification

Eq TypeAppError Source #

Since: 1.0.0

Instance details

Defined in Covenant.Internal.Unification

data RenameError Source #

Ways in which the renamer can fail.

Since: 1.1.0

Constructors

InvalidAbstractionReference Int (Index "tyvar")

An attempt to reference an abstraction in a scope where this abstraction doesn't exist, but where the scope itself does exist. Put another way: This gets thrown when the argument index of an abstraction inconsistent with the Count of the scope its DB index refers to. First field is the true level, second is the index that was requested.

Since: 1.2.0

InvalidScopeReference Int (Index "tyvar")

An abstraction refers to a scope which does not exist. That is: The abstraction's DeBruijn index points to a scope "higher than" the top-level scope.

Since: 1.2.0

Instances

Instances details
Show RenameError Source # 
Instance details

Defined in Covenant.Internal.Rename

Eq RenameError Source # 
Instance details

Defined in Covenant.Internal.Rename

data UnRenameError Source #

Ways in which the un-renamer can fail.

Since: 1.2.0

Constructors

UnRenameWildCard Renamed

We tried to un-rename a wildcard. This means something has gone very wrong internally. @since 1.2.0

NegativeDeBruijn Int

We received a negative DeBruijn in our true level calculation. This is impossible, and indicates another internal malfunction or bug

Instances

Instances details
Show UnRenameError Source #

Since: 1.2.0

Instance details

Defined in Covenant.Internal.Rename

Eq UnRenameError Source #

Since: 1.2.0

Instance details

Defined in Covenant.Internal.Rename

data EncodingArgErr a Source #

Indicates that we tried to instantiate a polymorphic data type using a type whose encoding is incompatible. The most common case of this is when we have a 'polymorphic' data type that uses some kind of Data encoding and we try to instantiate it with a type which has a SOP encoding.

Since: 1.2.0

Constructors

EncodingArgMismatch TyName (ValT a)

First field is a constructor name for the type we tried to instantiate, second field is the bad instantiator.

Since: 1.2.0

Instances

Instances details
Show a => Show (EncodingArgErr a) Source # 
Instance details

Defined in Covenant.Internal.KindCheck

Eq a => Eq (EncodingArgErr a) Source # 
Instance details

Defined in Covenant.Internal.KindCheck

data CovenantTypeError Source #

An error that can arise during the construction of an ASG by programmatic means.

Since: 1.0.0

Constructors

BrokenIdReference Id

An Id has no corresponding node. This error should not arise under normal circumstances: the most likely explanation is that you're using an Id that was made by a different ASG builder computation.

Since: 1.0.0

ForceCompType (CompT AbstractTy)

Computation-typed nodes can't be forced, but we tried anyway.

Since: 1.0.0

ForceNonThunk (ValT AbstractTy)

Value-typed nodes that aren't thunks can't be forced, but we tried anyway.

Since: 1.0.0

ForceError

Error nodes can't be forced, but we tried anyway.

Since: 1.0.0

ThunkValType (ValT AbstractTy)

Value-typed nodes can't be thunked, but we tried anyway.

Since: 1.0.0

ThunkError

Error nodes can't be thunked, but we tried anyway.

Since: 1.0.0

ApplyToValType (ValT AbstractTy)

Arguments can't be applied to a value-typed node, but we tried anyway.

Since: 1.0.0

ApplyToError

Arguments can't be applied to error nodes, but we tried anyway.

Since: 1.0.0

ApplyCompType (CompT AbstractTy)

Computation-typed nodes can't be applied as arguments, but we tried anyway.

Since: 1.0.0

RenameFunctionFailed (CompT AbstractTy) RenameError

Renaming the function in an application failed.

Since: 1.0.0

RenameArgumentFailed (ValT AbstractTy) RenameError

Renaming an argument in an application failed.

Since: 1.0.0

UnificationError TypeAppError

We failed to unify an expected argument type with the type of the argument we were actually given.

Since: 1.0.0

NoSuchArgument DeBruijn (Index "arg")

An argument was requested that doesn't exist.

Since: 1.0.0

ReturnCompType (CompT AbstractTy)

Can't return a computation-typed node, but we tried anyway.

Since: 1.0.0

LambdaResultsInCompType (CompT AbstractTy)

The body of a lambda results in a value-typed node, which isn't allowed.

Since: 1.2.0

LambdaResultsInNonReturn (CompT AbstractTy)

The body of a lambda results in a computation-typed node which isn't a return, which isn't allowed.

Since: 1.0.0

ReturnWrapsError

A lambda body's return is wrapping an error, instead of being directly an error. This should not happen under normal circumstances and is most certainly a bug.

Since: 1.0.0

ReturnWrapsCompType (CompT AbstractTy)

We tried to return a computation-typed node, but this isn't allowed.

Since: 1.0.0

WrongReturnType (ValT AbstractTy) (ValT AbstractTy)

The result of an application is not what the computation being applied expected.

First field is the expected type, the second is what we actually got.

Since: 1.0.0

EncodingError (EncodingArgErr AbstractTy)

Wraps an encoding argument mismatch error from KindCheck

Since: 1.1.0

CataAlgebraWrongArity Int

The first argument to a catamorphism wasn't an algebra, as it had the wrong arity.

Since: 1.2.0

CataNotAnAlgebra ASGNodeType

The first argument to a catamorphism wasn't an algebra.

Since: 1.1.0

CataApplyToNonValT ASGNodeType

The second argument to a catamorphism wasn't a value type.

Since: 1.1.0

CataNonRigidAlgebra (CompT AbstractTy) 
CataWrongBuiltinType BuiltinFlatT

The second argument to a catamorphism is a builtin type, but not one we can eliminate with a catamorphism.

Since: 1.1.0

CataWrongValT (ValT AbstractTy)

The second argument to a catamorphism is a value type, but not one we can eliminate with a catamorphism. Usually, this means it's a variable.

Since: 1.1.0

CataNoSuchType TyName

We requested a catamorphism for a type that doesn't exist.

Since: 1.2.0

CataNoBaseFunctorForType TyName

We requested a catamorphism for a type without a base functor.

Since: 1.2.0

CataUnsuitable (CompT AbstractTy) (ValT AbstractTy)

The provided algebra is not suitable for the given type.

Since: 1.1.0

OutOfScopeTyVar DeBruijn (Index "tyvar")

Someone attempted to construct a tyvar using a DB index or argument position which refers to a scope (or argument) that does not exist.

Since: 1.2.0

FailedToRenameInstantiation RenameError

We failed to rename an "instantiation type" supplied to app.

Since: 1.2.0

UndoRenameFailure UnRenameError

Un-renaming failed.

Since: 1.2.0

TypeDoesNotExist TyName

We tried to look up the DatatypeInfo corresponding to a TyName and came up empty handed.

Since: 1.2.0

DatatypeInfoRenameError RenameError

We tried to rename a DatatypeInfo and failed.

Since: 1.2.0

ConstructorDoesNotExistForType TyName ConstructorName

We tried to look up a constructor for a given type. The type exists, but the constructor does not.

Since: 1.2.0

IntroFormWrongNumArgs TyName ConstructorName Int

When using the helper function to construct an introduction form, the type and constructor exist but the number of fields provided as an argument does not match the number of declared fields. The Int is the incorrect number of supplied fields.

Since: 1.2.0

IntroFormErrorNodeField TyName ConstructorName (Vector Ref)

The user passed an error node as an argument to a datatype into form. We return the arguments given to dataConstructor in the error.

Since: 1.2.0

UndeclaredOpaquePlutusDataCtor (Set PlutusDataConstructor) ConstructorName

The user tried to construct an introduction form using a Plutus Data constructor not found in the opaque datatype declaration.

Since: 1.2.0

InvalidOpaqueField (Set PlutusDataConstructor) ConstructorName [ValT Renamed]

The user tried to construct an introduction form with a valid Plutus Data constructor, but supplied a Ref to a field of the wrong type.

Since: 1.2.0

MatchNonValTy ASGNodeType 
MatchNonThunkBBF (ValT Renamed)

Internal error: we found a base functor Boehm-Berrarducci form that isn't a thunk after instantiation during pattern matching.Somehow we got a BFBB that is something other than a thunk after instantiation during pattern matching.

This should not normally happen: let us know if you see this error!

Since: 1.2.0

MatchRenameBBFail RenameError

We encountered a rename error during pattern matching. This will refer to either the Boehm-Berrarducci form, or the base functor Boehm-Berrarducci form, depending on what type we tried to match.

Since: 1.2.0

MatchRenameTyConArgFail RenameError

This indicates that we encountered an error when renaming the arguments to the type constructor of the scrutinee type during pattern matching. That is, if we're matching on Either a b, this means that either a or b failed to rename.

This should not normally happen: let us know if you see this error!

Since: 1.2.0

MatchPolymorphicHandler (ValT Renamed)

A user tried to use a polymorphic handler in a pattern match, which is not currently allowed.

Since: 1.2.0

MatchErrorAsHandler Ref

We tried to use an error node as a pattern match handler.

Since: 1.2.0

MatchNoBBForm TyName

The non-recursive branch of a pattern match needs a Boehm-Berrarducci form for the given type name, but it doesn't exist.

Since: 1.2.0

MatchNonDatatypeScrutinee (ValT AbstractTy)

Someone tried to match on something that isn't a datatype.

Since: 1.2.0

MatchNoDatatypeInfo TyName

The scrutinee is a datatype, be don't have it in our datatype dictionary.

Since: 1.2.0

data BoundTyVar Source #

Wrapper around an Arg that we know represents an in-scope type variable. @since 1.2.0

Instances

Instances details
Show BoundTyVar Source # 
Instance details

Defined in Covenant.ASG

Eq BoundTyVar Source # 
Instance details

Defined in Covenant.ASG

Ord BoundTyVar Source # 
Instance details

Defined in Covenant.ASG

Introducers

boundTyVar :: (MonadError CovenantTypeError m, MonadReader ASGEnv m) => DeBruijn -> Index "tyvar" -> m BoundTyVar Source #

Given a DeBruijn index (designating scope) and positional index (designating which variable in that scope we are interested in), retrieve an in-scope type variable.

This will error if we request a type variable in a scope that doesn't exist, or at a position that doesn't exist in that scope.

Since: 1.2.0

arg :: (MonadError CovenantTypeError m, MonadReader ASGEnv m) => DeBruijn -> Index "arg" -> m Arg Source #

Given a scope and a positional argument index, construct that argument. Will fail if that argument doesn't exist in the specified scope, or if the specified scope doesn't exist.

Since: 1.0.0

builtin1 :: MonadHashCons Id ASGNode m => OneArgFunc -> m Id Source #

Construct a node corresponding to the given Plutus primop.

Since: 1.0.0

builtin2 :: MonadHashCons Id ASGNode m => TwoArgFunc -> m Id Source #

As builtin1, but for two-argument primops.

Since: 1.0.0

builtin3 :: MonadHashCons Id ASGNode m => ThreeArgFunc -> m Id Source #

As builtin1, but for three-argument primops.

Since: 1.0.0

builtin6 :: MonadHashCons Id ASGNode m => SixArgFunc -> m Id Source #

As builtin1, but for six-argument primops.

Since: 1.1.0

force :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Ref -> m Id Source #

Given a reference to a thunk, turn it back into a computation. Will fail if the reference isn't a thunk.

Since: 1.0.0

lam :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => CompT AbstractTy -> m Ref -> m Id Source #

Given a desired type, and a computation which will construct a lambda body when executed (with the scope extended with the arguments the functions can expect), construct a lambda.

Important note

This combinator works slightly differently to the others in this module. This is required because, due to hash consing, an ASG is typically built 'bottom-up', whereas function arguments (and their scopes) are necessarily top-down. Thus, we need to 'delay' the construction of a lambda's body to ensure that proper scoped argument information can be given to it, hence why the argument being passed is an m Ref.

Since: 1.2.0

err :: MonadHashCons Id ASGNode m => m Id Source #

Construct the error node.

Since: 1.0.0

lit :: MonadHashCons Id ASGNode m => AConstant -> m Id Source #

Construct a node corresponding to the given constant.

Since: 1.0.0

thunk :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m) => Id -> m Id Source #

Given an Id referring to a computation, build a thunk wrapping it. Will fail if the Id does not refer to a computation node.

Since: 1.0.0

dataConstructor :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => TyName -> ConstructorName -> Vector Ref -> m Id Source #

Introduce a data constructor.

The first argument is a type name (for example, "Maybe"). The second argument is a constructor of that type (for example, "Just" or "Nothing"). The third argument are the values to 'fill in' all the fields of the constructor requested.

Note

dataConstructor yields thunks, which must be forced, and then possibly have type arguments applied to them. The reason for this is subtle, but important. Consider the Nothing constructor of Maybe: as this has no fields, we cannot use the field type to determine what the type argument to Maybe should be in this case. As datatype terms are values, they do not bind type variables, and thus, we cannot have a return type that makes sense in this case.

We resolve this problem by returning a thunk. In the case of our example, Nothing would produce a . !Maybe a.

Since: 1.2.0

Eliminators

app :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => Id -> Vector Ref -> Vector (Wedge BoundTyVar (ValT Void)) -> m Id Source #

Performs both term and type application. More precisely, given:

  • An Id referring to a computation; and
  • A Vector of Refs for the desired term arguments to the computation, in order; and
  • A Vector of (optional) type arguments to the computation, also in order.

we produce the result of that application.

This can fail for a range of reasons:

  • Type mismatch between what the computation expects and what it's given
  • Too many or too few arguments
  • Not a computation type for Id argument
  • Not value types for Refs
  • Renaming failures (likely due to a malformed function or argument type)

Note

We use the Wedge data type to designate type arguments, as it can represent the three possibilities we need:

  • 'Infer this argument', specified as Nowhere.
  • 'Use this type variable in our scope', specified as Here.
  • 'Use this concrete type', specified as There.

Since: 1.2.0

cata :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => Ref -> Ref -> m Id Source #

Given a Ref to an algebra (that is, something taking a base functor and producing some result), and a Ref to a value associated with that base functor, build a catamorphism to tear it down. This can fail for a range of reasons:

  • First Ref is not a thunk taking one argument
  • The argument to the thunk isn't a base functor, or isn't a suitable base functor for the second argument
  • Second argument is not a value type

Note

cata cannot work with non-rigid algebras; that is, all algebras must be functions that bind no type variables of their own.

Since: 1.1.0

match :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => Ref -> Vector Ref -> m Id Source #

Perform a pattern match. The first argument is the value to be matched on, and the second argument is a Vector of 'handlers' for each possible 'arm' of the type of the value to be matched on.

All handlers must be thunks, and must all return the same (concrete) result. Polymorphic 'handlers' (that is, thunks whose computation binds type variables of its own) will fail to compile.

Since: 1.2.0

Helpers

ctor :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => TyName -> ConstructorName -> Vector Ref -> Vector (Wedge BoundTyVar (ValT Void)) -> m Id Source #

Constructs a datatype value at given constructor. This is different to dataConstructor, as it doesn't produce a thunk.

The third argument is a Vector of values to 'fill in' all the fields required by the stated constructor. The fourth argument is a Vector of 'type instantiations', which allow 'concretification' of any lingering polymorphic type variables which are not determined by the field values given as the third argument.

Example

Consider Left 3. In this case, the field only determines the first type argument to the Either data type, and if we used dataConstructor, we would be left with a thunk of type a . !Either Integer a. Using ctor, we can immediately specify what a should be, and unwrap the thunk.

Since: 1.2.0

lazyLam :: (MonadHashCons Id ASGNode m, MonadError CovenantTypeError m, MonadReader ASGEnv m) => CompT AbstractTy -> m Ref -> m Id Source #

As lam, but produces a thunk value instead of a computation.

Since: 1.2.0

dtype :: TyName -> [ValT AbstractTy] -> ValT AbstractTy Source #

Helper to avoid using fromList when defining data types.

Since: 1.2.0

Environment

defaultDatatypes :: Map TyName (DatatypeInfo AbstractTy) Source #

A standard collection of types required for almost any realistic script. This includes non-'flat' builtin types (such as lists and pairs), as well as all types required by the ledger (including types like Maybe).

Since: 1.1.0

Function

runASGBuilder :: Map TyName (DatatypeInfo AbstractTy) -> ASGBuilder a -> Either CovenantError ASG Source #

Executes an ASGBuilder to make a 'finished' ASG.

Since: 1.0.0

data ASGEnv Source #

The environment used when 'building up' an ASG. This type is exposed only for testing, or debugging, and should not be used in general by those who just want to build an ASG.

Since: 1.2.0

Instances

Instances details
MonadReader ASGEnv ASGBuilder Source #

Since: 1.1.0

Instance details

Defined in Covenant.ASG

Methods

ask :: ASGBuilder ASGEnv #

local :: (ASGEnv -> ASGEnv) -> ASGBuilder a -> ASGBuilder a #

reader :: (ASGEnv -> a) -> ASGBuilder a #

MonadReader ASGEnv DebugASGBuilder Source #

Since: 1.1.0

Instance details

Defined in Covenant.Test

(k ~ A_Lens, a ~ Map TyName (DatatypeInfo AbstractTy), b ~ Map TyName (DatatypeInfo AbstractTy)) => LabelOptic "datatypeInfo" k ASGEnv ASGEnv a b Source #

Since: 1.2.0

Instance details

Defined in Covenant.ASG

(k ~ A_Lens, a ~ ScopeInfo, b ~ ScopeInfo) => LabelOptic "scopeInfo" k ASGEnv ASGEnv a b Source #

Since: 1.2.0

Instance details

Defined in Covenant.ASG