lorentz-0.16.0: EDSL for the Michelson Language
Safe HaskellSafe-Inferred
LanguageHaskell2010

Lorentz.StoreClass

Description

This module provides storage interfaces.

Whenever you need to write a generic code applicable to different storage formats, consider using this module.

Use methods like stToField and stUpdate to work with storage from your code.

To explain how e.g. required fields are obtainable from your storage you define StoreHasField instance (and a similar case is for other typeclasses). We provide the most common building blocks for implementing these instances, see Implementations section.

OverloadedRecordDot is supported for field access, e.g. like this:

stSetField this.sField1.ssField1.gField

(note this is mandatory)

However, there are some kinks. When using Lorentz with RebindableSyntax and OverloadedRecordDot, you'll want to hide getField import from Lorentz or Lorentz.ADT, and instead import GHC.Records, otherwise GHC will try to use Lorentz.ADT.getField when desugaring record dots and produce inscrutable error messages like this:

• Expected a type, but
  ‘"gField"’ has kind
  ‘ghc-prim-0.9.0:GHC.Types.Symbol’

If you need to use both Lorentz.ADT.getField and record dots, consider importing Lorentz.ADT qualified.

Synopsis

Preliminary

type FieldRefKind = FieldRefTag -> Type Source #

Open kind for various field references.

The simplest field reference could be Label, pointing to a field by its name, but we also support more complex scenarios like deep fields identifiers.

data FieldRefTag Source #

Instances

Instances details
KnownFieldRef SelfRef Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject SelfRef = (fr :: FieldRefKind) Source #

StoreHasField store SelfRef store Source # 
Instance details

Defined in Lorentz.StoreClass

(StoreHasField store field substore, StoreHasField substore subfield ty, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters substore) => StoreHasField store (field :-| subfield :: FieldRefTag -> Type) ty Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeFieldOps :: StoreFieldOps store (field :-| subfield) ty Source #

(StoreHasField store field substore, StoreHasSubmap substore subfield key value, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters store, Dupable substore) => StoreHasSubmap store (field :-| subfield :: FieldRefTag -> Type) key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps store (field :-| subfield) key value Source #

(NiceComparable key, Ord key, Dupable key) => StoreHasSubmap (Set key) SelfRef key () Source # 
Instance details

Defined in Lorentz.StoreClass

KnownFieldRef (FieldAlias alias :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (FieldAlias alias) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (FieldAlias alias) p Source #

(NiceComparable key, KnownValue value) => StoreHasSubmap (Map key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (Map key value) SelfRef key value Source #

(NiceComparable key, KnownValue value) => StoreHasSubmap (BigMap key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (BigMap key value) SelfRef key value Source #

FieldRefHasFinalName r => FieldRefHasFinalName (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefFinalName (l :-| r) :: Symbol Source #

(KnownFieldRef l, KnownFieldRef r) => KnownFieldRef (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (l :-| r) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (l :-| r) p Source #

type FieldRefObject SelfRef Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefObject (FieldAlias alias :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefFinalName (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefObject (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefObject (l :-| r :: FieldRefTag -> Type) = l :-| r

class KnownFieldRef (ty :: k) where Source #

For a type-level field reference - an associated term-level representation.

This is similar to singletons Sing + SingI pair but has small differences:

  • Dedicated to field references, thus term-level thing has FieldRefKind kind.
  • The type of term-level value (FieldRefObject ty) determines the kind of the reference type.

Associated Types

type FieldRefObject ty = (fr :: FieldRefKind) | fr -> ty Source #

Instances

Instances details
KnownSymbol name => KnownFieldRef (name :: Symbol) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject name = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject name p Source #

KnownFieldRef SelfRef Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject SelfRef = (fr :: FieldRefKind) Source #

KnownFieldRef (FieldAlias alias :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (FieldAlias alias) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (FieldAlias alias) p Source #

(KnownFieldRef l, KnownFieldRef r) => KnownFieldRef (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (l :-| r) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (l :-| r) p Source #

data FieldName (n :: Symbol) (p :: FieldRefTag) Source #

The simplest field reference - just a name. Behaves similarly to Label.

type FieldRef name = FieldRefObject name 'FieldRefTag Source #

Some kind of reference to a field.

The idea behind this type is that in trivial case (name :: Symbol) it can be instantiated with a mere label, but it is generic enough to allow complex field references as well.

type FieldSymRef name = FieldRef (name :: Symbol) Source #

Version of FieldRef restricted to symbolic labels.

FieldSymRef name ≡ FieldName name 'FieldRefTag

fieldNameToLabel :: FieldSymRef n -> Label n Source #

Convert a symbolic FieldRef to a label, useful for compatibility with other interfaces.

fieldNameFromLabel :: Label n -> FieldSymRef n Source #

Convert a label to FieldRef, useful for compatibility with other interfaces.

class FieldRefHasFinalName fr where Source #

Provides access to the direct name of the referred field.

This is used in stToFieldNamed.

Associated Types

type FieldRefFinalName fr :: Symbol Source #

Instances

Instances details
FieldRefHasFinalName (name :: Symbol) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefFinalName name :: Symbol Source #

FieldRefHasFinalName r => FieldRefHasFinalName (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefFinalName (l :-| r) :: Symbol Source #

Class

class StoreHasField store fname ftype | store fname -> ftype where Source #

Provides operations on fields for storage.

Methods

storeFieldOps :: StoreFieldOps store fname ftype Source #

Instances

Instances details
HasFieldOfType store fname ftype => StoreHasField store (fname :: Symbol) ftype Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeFieldOps :: StoreFieldOps store fname ftype Source #

StoreHasField store SelfRef store Source # 
Instance details

Defined in Lorentz.StoreClass

(StoreHasField store field substore, StoreHasField substore subfield ty, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters substore) => StoreHasField store (field :-| subfield :: FieldRefTag -> Type) ty Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeFieldOps :: StoreFieldOps store (field :-| subfield) ty Source #

data StoreFieldOps store fname ftype Source #

Datatype containing the full implementation of StoreHasField typeclass.

We use this grouping because in most cases the implementation will be chosen among the default ones, and initializing all methods at once is simpler and more consistent. (One can say that we are trying to emulate the DerivingVia extension.)

Constructors

StoreFieldOps 

Fields

class StoreHasSubmap store mname key value | store mname -> key value where Source #

Provides operations on submaps of storage.

Methods

storeSubmapOps :: StoreSubmapOps store mname key value Source #

Instances

Instances details
(StoreHasField store name submap, StoreHasSubmap submap SelfRef key value, KnownSymbol name, HasDupableGetters store, Dupable submap) => StoreHasSubmap store (name :: Symbol) key value Source #

Provides access to the submap via the respective field.

Tricky storages that consolidate submaps in a non-trivial way can define instances overlapping this one.

Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps store name key value Source #

(StoreHasField store field substore, StoreHasSubmap substore subfield key value, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters store, Dupable substore) => StoreHasSubmap store (field :-| subfield :: FieldRefTag -> Type) key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps store (field :-| subfield) key value Source #

(NiceComparable key, Ord key, Dupable key) => StoreHasSubmap (Set key) SelfRef key () Source # 
Instance details

Defined in Lorentz.StoreClass

(NiceComparable key, KnownValue value) => StoreHasSubmap (Map key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (Map key value) SelfRef key value Source #

(NiceComparable key, KnownValue value) => StoreHasSubmap (BigMap key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (BigMap key value) SelfRef key value Source #

data StoreSubmapOps store mname key value Source #

Datatype containing the full implementation of StoreHasSubmap typeclass.

We use this grouping because in most cases the implementation will be chosen among the default ones, and initializing all methods at once is simpler and more consistent. (One can say that we are trying to emulate the DerivingVia extension.)

Constructors

StoreSubmapOps 

Fields

class StoreHasEntrypoint store epName epParam epStore | store epName -> epParam epStore where Source #

Provides operations on stored entrypoints.

store is the storage containing both the entrypoint epName (note: it has to be in a BigMap to take advantage of lazy evaluation) and the epStore field this operates on.

Methods

storeEpOps :: StoreEntrypointOps store epName epParam epStore Source #

data StoreEntrypointOps store epName epParam epStore Source #

Datatype containing the full implementation of StoreHasEntrypoint typeclass.

We use this grouping because in most cases the implementation will be chosen among the default ones, and initializing all methods at once is simpler and more consistent. (One can say that we are trying to emulate the DerivingVia extension.)

Constructors

StoreEntrypointOps 

Fields

Useful type synonyms

type EntrypointLambda param store = Lambda (param, store) ([Operation], store) Source #

Type synonym for a Lambda that can be used as an entrypoint

type EntrypointsField param store = BigMap MText (EntrypointLambda param store) Source #

Type synonym of a BigMap mapping MText (entrypoint names) to EntrypointLambda.

This is useful when defining instances of StoreHasEntrypoint as a storage field containing one or more entrypoints (lambdas) of the same type.

Expressing constraints on storage

data k ~> v infix 9 Source #

Indicates a submap with given key and value types.

data param ::-> store infix 9 Source #

Indicates a stored entrypoint with the given param and store types.

type family StorageContains store (content :: [NamedField]) :: Constraint where ... Source #

Concise way to write down constraints with expected content of a storage.

Use it like follows:

type StorageConstraint store = StorageContains store
  [ "fieldInt" := Int
  , "fieldNat" := Nat
  , "epsToNat" := Int ::-> Nat
  , "balances" := Address ~> Int
  ]

Note that this won't work with complex field references, they have to be included using e.g. StoreHasField manually.

Equations

StorageContains _ '[] = () 
StorageContains store ((n := Identity ty) ': ct) = (StoreHasField store n ty, StorageContains store ct) 
StorageContains store ((n := (k ~> v)) ': ct) = (StoreHasSubmap store n k v, StorageContains store ct) 
StorageContains store ((n := (ep ::-> es)) ': ct) = (StoreHasEntrypoint store n ep es, StorageContains store ct) 
StorageContains store ((n := ty) ': ct) = (StoreHasField store n ty, StorageContains store ct) 

Methods to work with storage

stToField :: StoreHasField store fname ftype => FieldRef fname -> (store : s) :-> (ftype : s) Source #

Pick storage field.

stGetField :: (StoreHasField store fname ftype, Dupable ftype, HasDupableGetters store) => FieldRef fname -> (store : s) :-> (ftype : (store : s)) Source #

Get storage field, preserving the storage itself on stack.

stToFieldNamed :: (StoreHasField store fname ftype, FieldRefHasFinalName fname) => FieldRef fname -> (store : s) :-> ((FieldRefFinalName fname :! ftype) : s) Source #

Pick storage field retaining a name label attached.

For complex refs this tries to attach the immediate name of the referred field.

stGetFieldNamed :: (StoreHasField store fname ftype, FieldRefHasFinalName fname, Dupable ftype, HasDupableGetters store) => FieldRef fname -> (store : s) :-> ((FieldRefFinalName fname :! ftype) : (store : s)) Source #

Version of stToFieldNamed that preserves the storage on stack.

stSetField :: StoreHasField store fname ftype => FieldRef fname -> (ftype : (store : s)) :-> (store : s) Source #

Update storage field.

stMem :: StoreHasSubmap store mname key value => FieldRef mname -> (key : (store : s)) :-> (Bool : s) Source #

Check value presence in storage.

stGet :: (StoreHasSubmap store mname key value, KnownValue value) => FieldRef mname -> (key : (store : s)) :-> (Maybe value : s) Source #

Get value in storage.

stUpdate :: StoreHasSubmap store mname key value => FieldRef mname -> (key : (Maybe value : (store : s))) :-> (store : s) Source #

Update a value in storage.

stGetAndUpdate :: StoreHasSubmap store mname key value => FieldRef mname -> (key : (Maybe value : (store : s))) :-> (Maybe value : (store : s)) Source #

Atomically get and update a value in storage.

stDelete :: forall store mname key value s. StoreHasSubmap store mname key value => FieldRef mname -> (key : (store : s)) :-> (store : s) Source #

Delete a value in storage.

stInsert :: StoreHasSubmap store mname key value => FieldRef mname -> (key : (value : (store : s))) :-> (store : s) Source #

Add a value in storage.

stInsertNew :: (StoreHasSubmap store mname key value, Dupable key) => FieldRef mname -> (forall s0 any. (key : s0) :-> any) -> (key : (value : (store : s))) :-> (store : s) Source #

Add a value in storage, but fail if it will overwrite some existing entry.

stEntrypoint :: (StoreHasEntrypoint store epName epParam epStore, Dupable store) => Label epName -> (epParam : (store : s)) :-> (([Operation], store) : s) Source #

Extracts and executes the epName entrypoint lambda from storage, returing the updated full storage (store) and the produced Operations.

stToEpLambda :: StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : s) Source #

Pick stored entrypoint lambda.

stGetEpLambda :: (StoreHasEntrypoint store epName epParam epStore, Dupable store) => Label epName -> (store : s) :-> (EntrypointLambda epParam epStore : (store : s)) Source #

Get stored entrypoint lambda, preserving the storage itself on the stack.

stSetEpLambda :: (StoreHasEntrypoint store epName epParam epStore, HasDupableGetters store) => Label epName -> (EntrypointLambda epParam epStore : (store : s)) :-> (store : s) Source #

Stores the entrypoint lambda in the storage. Fails if already set.

stToEpStore :: StoreHasEntrypoint store epName epParam epStore => Label epName -> (store : s) :-> (epStore : s) Source #

Pick the sub-storage that the entrypoint operates on.

stGetEpStore :: (StoreHasEntrypoint store epName epParam epStore, Dupable store) => Label epName -> (store : s) :-> (epStore : (store : s)) Source #

Get the sub-storage that the entrypoint operates on, preserving the storage itself on the stack.

stSetEpStore :: StoreHasEntrypoint store epName epParam epStore => Label epName -> (epStore : (store : s)) :-> (store : s) Source #

Update the sub-storage that the entrypoint operates on.

sopGetField :: (Dupable ftype, HasDupableGetters store) => StoreFieldOps store fname ftype -> FieldRef fname -> (store : s) :-> (ftype : (store : s)) Source #

Simplified version of sopGetFieldOpen where res is ftype.

sopSetField :: StoreFieldOps store fname ftype -> FieldRef fname -> (ftype : (store : s)) :-> (store : s) Source #

Simplified version of sopSetFieldOpen where res is ftype.

Implementations

storeFieldOpsADT :: HasFieldOfType dt fname ftype => StoreFieldOps dt (fname :: Symbol) ftype Source #

Implementation of StoreHasField for case of datatype keeping a pack of fields.

storeEntrypointOpsADT :: (HasFieldOfType store epmName (EntrypointsField epParam epStore), HasFieldOfType store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore Source #

Implementation of StoreHasEntrypoint for a datatype keeping a pack of fields, among which one contains the entrypoint and another is what such entrypoint operates on.

storeEntrypointOpsFields :: (StoreHasField store epmName (EntrypointsField epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore Source #

Implementation of StoreHasEntrypoint for a datatype that has a StoreHasField for an EntrypointsField that contains the entrypoint and a StoreHasField for the field such entrypoint operates on.

storeEntrypointOpsSubmapField :: (StoreHasSubmap store epmName MText (EntrypointLambda epParam epStore), StoreHasField store epsName epStore, KnownValue epParam, KnownValue epStore) => Label epmName -> Label epsName -> StoreEntrypointOps store epName epParam epStore Source #

Implementation of StoreHasEntrypoint for a datatype that has a StoreHasSubmap that contains the entrypoint and a StoreHasField for the field such entrypoint operates on.

storeFieldOpsDeeper :: (HasFieldOfType storage fieldsPartName fields, StoreHasField fields fname ftype, HasDupableGetters fields) => FieldRef fieldsPartName -> StoreFieldOps storage fname ftype Source #

Implementation of StoreHasField for a data type which has an instance of StoreHasField inside. For instance, it can be used for top-level storage.

storeSubmapOpsDeeper :: (HasFieldOfType storage bigMapPartName fields, StoreHasSubmap fields SelfRef key value, HasDupableGetters storage, Dupable fields) => FieldRef bigMapPartName -> StoreSubmapOps storage mname key value Source #

Implementation of StoreHasSubmap for a data type which has an instance of StoreHasSubmap inside. For instance, it can be used for top-level storage.

storeEntrypointOpsDeeper :: (HasFieldOfType store nameInStore substore, StoreHasEntrypoint substore epName epParam epStore, HasDupableGetters store, Dupable substore) => FieldRef nameInStore -> StoreEntrypointOps store epName epParam epStore Source #

Implementation of StoreHasEntrypoint for a data type which has an instance of StoreHasEntrypoint inside. For instance, it can be used for top-level storage.

storeFieldOpsReferTo :: FieldRef name -> StoreFieldOps storage name field -> StoreFieldOps storage desiredName field Source #

Pretend that given StoreFieldOps implementation is made up for field with name desiredName, not its actual name. Logic of the implementation remains the same.

See also storeSubmapOpsReferTo.

storeSubmapOpsReferTo :: FieldRef name -> StoreSubmapOps storage name key value -> StoreSubmapOps storage desiredName key value Source #

Pretend that given StoreSubmapOps implementation is made up for submap with name desiredName, not its actual name. Logic of the implementation remains the same.

Use case: imagine that your code requires access to submap named X, but in your storage that submap is called Y. Then you implement the instance which makes X refer to Y:

instance StoreHasSubmap Store X Key Value where
  storeSubmapOps = storeSubmapOpsReferTo #Y storeSubmapOpsForY

mapStoreFieldOps :: forall field1 field2 store name. KnownValue field1 => LIso field1 field2 -> StoreFieldOps store name field1 -> StoreFieldOps store name field2 Source #

Change field operations so that they work on a modified field.

For instance, to go from StoreFieldOps Storage "name" Integer to StoreFieldOps Storage "name" (value :! Integer) you can use mapStoreFieldOps (namedIso #value)

mapStoreSubmapOpsKey :: Fn key2 key1 -> StoreSubmapOps store name key1 value -> StoreSubmapOps store name key2 value Source #

Change submap operations so that they work on a modified key.

mapStoreSubmapOpsValue :: (KnownValue value1, KnownValue value2) => LIso value1 value2 -> StoreSubmapOps store name key value1 -> StoreSubmapOps store name key value2 Source #

Change submap operations so that they work on a modified value.

storeEntrypointOpsReferTo :: Label epName -> StoreEntrypointOps store epName epParam epStore -> StoreEntrypointOps store desiredName epParam epStore Source #

Pretend that given StoreEntrypointOps implementation is made up for entrypoint with name desiredName, not its actual name. Logic of the implementation remains the same.

See also storeSubmapOpsReferTo.

composeStoreFieldOps :: HasDupableGetters substore => FieldRef nameInStore -> StoreFieldOps store nameInStore substore -> StoreFieldOps substore nameInSubstore field -> StoreFieldOps store nameInSubstore field Source #

Chain two implementations of field operations.

Suits for a case when your store does not contain its fields directly rather has a nested structure.

composeStoreSubmapOps :: (HasDupableGetters store, Dupable substore) => FieldRef nameInStore -> StoreFieldOps store nameInStore substore -> StoreSubmapOps substore mname key value -> StoreSubmapOps store mname key value Source #

Chain implementations of field and submap operations.

This requires Dupable substore for simplicity, in most cases it is possible to use a different chaining (nameInStore :-| mname :-| this) to avoid that constraint. If this constraint is still an issue, please create a ticket.

sequenceStoreSubmapOps :: forall store substore value name subName key1 key2. (NiceConstant substore, KnownValue value, Dupable (key1, key2), Dupable store) => FieldRef name -> LIso (Maybe substore) substore -> StoreSubmapOps store name key1 substore -> StoreSubmapOps substore subName key2 value -> StoreSubmapOps store subName (key1, key2) value Source #

Chain implementations of two submap operations sets. Used to provide shortcut access to a nested submap.

This is very inefficient since on each access to substore it has to be serialized/deserialized. Use this implementation only if due to historical reasons migrating storage is difficult.

LIso (Maybe substore) substore argument describes how to get substore value if it was absent in map and how to detect when it can be safely removed.

Example of use: sequenceStoreSubmapOps #mySubmap nonDefIso storeSubmapOps storeSubmapOps

composeStoreEntrypointOps :: (HasDupableGetters store, Dupable substore) => FieldRef nameInStore -> StoreFieldOps store nameInStore substore -> StoreEntrypointOps substore epName epParam epStore -> StoreEntrypointOps store epName epParam epStore Source #

zoomStoreSubmapOps :: forall store submapName nameInSubmap key value subvalue. (NiceConstant value, NiceConstant subvalue, Dupable key, Dupable store) => FieldRef submapName -> LIso (Maybe value) value -> LIso (Maybe subvalue) subvalue -> StoreSubmapOps store submapName key value -> StoreFieldOps value nameInSubmap subvalue -> StoreSubmapOps store nameInSubmap key subvalue Source #

Turn submap operations into operations on a part of the submap value.

Normally, if you need this set of operations, it would be better to split your submap into several separate submaps, each operating with its own part of the value. This set of operations is pretty inefficient and exists only as a temporary measure, if due to historical reasons you have to leave storage format intact.

This implementation puts no distinction between value == Nothing and value == Just defValue cases. Getters, when notice a value equal to the default value, report its absence. Setters tend to remove the value from submap when possible.

LIso (Maybe value) value and LIso (Maybe subvalue) subvalue arguments describe how to get a value if it was absent in map and how to detect when it can be safely removed from map.

Example of use: zoomStoreSubmapOps #mySubmap nonDefIso nonDefIso storeSubmapOps storeFieldOpsADT

Storage generation

mkStoreEp :: Label epName -> EntrypointLambda epParam epStore -> EntrypointsField epParam epStore Source #

Utility to create EntrypointsFields from an entrypoint name (epName) and an EntrypointLambda implementation. Note that you need to merge multiple of these (with <>) if your field contains more than one entrypoint lambda.

Complex field references

data ((l :: k1) :-| (r :: k2)) (p :: FieldRefTag) infixr 8 Source #

Refer to a nested entry in storage.

Example: stToField (#a :-| #b) fetches field b in the type under field a.

If this syntax seems overly verbose, you can try using OverloadedRecordDot. See module documentation for comments on that.

Constructors

(FieldRef l) :-| (FieldRef r) infixr 8 

Instances

Instances details
(KnownSymbol field, y ~ FieldRefObject ((l :-| r) :-| field), p ~ 'FieldRefTag) => HasField (field :: Symbol) ((l :-| r) p) (y p) Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

getField :: (l :-| r) p -> y p #

(StoreHasField store field substore, StoreHasField substore subfield ty, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters substore) => StoreHasField store (field :-| subfield :: FieldRefTag -> Type) ty Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeFieldOps :: StoreFieldOps store (field :-| subfield) ty Source #

(StoreHasField store field substore, StoreHasSubmap substore subfield key value, KnownFieldRef field, KnownFieldRef subfield, HasDupableGetters store, Dupable substore) => StoreHasSubmap store (field :-| subfield :: FieldRefTag -> Type) key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps store (field :-| subfield) key value Source #

FieldRefHasFinalName r => FieldRefHasFinalName (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefFinalName (l :-| r) :: Symbol Source #

(KnownFieldRef l, KnownFieldRef r) => KnownFieldRef (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (l :-| r) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (l :-| r) p Source #

type FieldRefFinalName (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefObject (l :-| r :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

type FieldRefObject (l :-| r :: FieldRefTag -> Type) = l :-| r

data SelfRef (p :: FieldRefTag) Source #

Refer to no particular field, access itself.

Constructors

SelfRef 

Instances

Instances details
(KnownSymbol field, y ~ FieldRefObject (SelfRef :-| field), p ~ 'FieldRefTag) => HasField (field :: Symbol) (SelfRef p) (y p) Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

getField :: SelfRef p -> y p #

KnownFieldRef SelfRef Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject SelfRef = (fr :: FieldRefKind) Source #

StoreHasField store SelfRef store Source # 
Instance details

Defined in Lorentz.StoreClass

(NiceComparable key, Ord key, Dupable key) => StoreHasSubmap (Set key) SelfRef key () Source # 
Instance details

Defined in Lorentz.StoreClass

(NiceComparable key, KnownValue value) => StoreHasSubmap (Map key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (Map key value) SelfRef key value Source #

(NiceComparable key, KnownValue value) => StoreHasSubmap (BigMap key value) SelfRef key value Source # 
Instance details

Defined in Lorentz.StoreClass

Methods

storeSubmapOps :: StoreSubmapOps (BigMap key value) SelfRef key value Source #

type FieldRefObject SelfRef Source # 
Instance details

Defined in Lorentz.StoreClass

this :: SelfRef p Source #

An alias for SelfRef.

Examples:

>>> push 5 # stMem this -$ (mempty :: Map Integer MText)
False
>>> stGetField this # pair -$ (5 :: Integer)
(5,5)

stNested :: StNestedImpl f SelfRef => f Source #

Provides alternative variadic interface for deep entries access.

Example: stToField (stNested #a #b #c)

data FieldAlias (alias :: k) (p :: FieldRefTag) Source #

Alias for a field reference.

This allows creating _custom_ field references; you will have to define the respective StoreHasField and StoreHasSubmap instances manually. Since this type occupies a different "namespace" than string labels and :-|, no overlappable instances will be necessary.

Example:

-- Shortcut for a deeply nested field X
data FieldX

instance StoreHasField Storage (FieldAlias FieldX) Integer where
  ...

accessX = stToField (stAlias @FieldX)

Note that alias type argument allows instantiations of any kind.

Instances

Instances details
KnownFieldRef (FieldAlias alias :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

Associated Types

type FieldRefObject (FieldAlias alias) = (fr :: FieldRefKind) Source #

Methods

mkFieldRef :: forall (p :: FieldRefTag). FieldRefObject (FieldAlias alias) p Source #

type FieldRefObject (FieldAlias alias :: FieldRefTag -> Type) Source # 
Instance details

Defined in Lorentz.StoreClass

stAlias :: forall alias. FieldRef (FieldAlias alias) Source #

Construct an alias at term level.

This requires passing the alias via type annotation.

type FieldNickname alias = FieldAlias (alias :: Symbol) Source #

Kind-restricted version of FieldAlias to work solely with string labels.

stNickname :: Label name -> FieldRef (FieldAlias name) Source #

Version of stAlias adopted to labels.

Orphan instances

(x ~ FieldName name, KnownSymbol name) => IsLabel name (x p) Source # 
Instance details

Methods

fromLabel :: x p #