Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Support for using de Bruijn indices for term and type names.
Synopsis
- newtype Index = Index Word64
- class HasIndex a where
- newtype DeBruijn = DeBruijn {}
- data NamedDeBruijn = NamedDeBruijn {
- ndbnString :: !Text
- ndbnIndex :: !Index
- newtype FakeNamedDeBruijn = FakeNamedDeBruijn {}
- newtype TyDeBruijn = TyDeBruijn DeBruijn
- newtype NamedTyDeBruijn = NamedTyDeBruijn NamedDeBruijn
- data FreeVariableError
- = FreeUnique !Unique
- | FreeIndex !Index
- class AsFreeVariableError r where
- _FreeVariableError :: Prism' r FreeVariableError
- _FreeUnique :: Prism' r Unique
- _FreeIndex :: Prism' r Index
- newtype Level = Level Integer
- data LevelInfo = LevelInfo {
- currentLevel :: Level
- levelMapping :: Bimap Unique Level
- declareUnique :: (MonadReader LevelInfo m, HasUnique name unique) => name -> m a -> m a
- declareBinder :: (MonadReader LevelInfo m, MonadQuote m) => m a -> m a
- withScope :: MonadReader LevelInfo m => m a -> m a
- getIndex :: MonadReader LevelInfo m => Unique -> (Unique -> m Index) -> m Index
- getUnique :: MonadReader LevelInfo m => Index -> (Index -> m Unique) -> m Unique
- unNameDeBruijn :: NamedDeBruijn -> DeBruijn
- unNameTyDeBruijn :: NamedTyDeBruijn -> TyDeBruijn
- fakeNameDeBruijn :: DeBruijn -> NamedDeBruijn
- fakeTyNameDeBruijn :: TyDeBruijn -> NamedTyDeBruijn
- nameToDeBruijn :: MonadReader LevelInfo m => (Unique -> m Index) -> Name -> m NamedDeBruijn
- tyNameToDeBruijn :: MonadReader LevelInfo m => (Unique -> m Index) -> TyName -> m NamedTyDeBruijn
- deBruijnToName :: MonadReader LevelInfo m => (Index -> m Unique) -> NamedDeBruijn -> m Name
- deBruijnToTyName :: MonadReader LevelInfo m => (Index -> m Unique) -> NamedTyDeBruijn -> m TyName
- freeIndexThrow :: (AsFreeVariableError e, MonadError e m) => Index -> m Unique
- freeIndexAsConsistentLevel :: (MonadReader LevelInfo m, MonadState (Map Level Unique) m, MonadQuote m) => Index -> m Unique
- freeUniqueThrow :: (AsFreeVariableError e, MonadError e m) => Unique -> m Index
- runDeBruijnT :: ReaderT LevelInfo m a -> m a
- deBruijnInitIndex :: Index
- toFake :: DeBruijn -> FakeNamedDeBruijn
- fromFake :: FakeNamedDeBruijn -> DeBruijn
Documentation
A relative index used for de Bruijn identifiers.
FIXME: downside of using newtype+Num instead of type-synonym is that `-Woverflowed-literals` does not work, e.g.: `DeBruijn (-1)` has no warning. To trigger the warning you have to bypass the Num and write `DeBruijn (Index -1)`. This can be revisited when we implement PLT-1053.
Instances
Enum Index Source # | |
Defined in PlutusCore.DeBruijn.Internal succ :: Index -> Index Source # pred :: Index -> Index Source # toEnum :: Int -> Index Source # fromEnum :: Index -> Int Source # enumFrom :: Index -> [Index] Source # enumFromThen :: Index -> Index -> [Index] Source # enumFromTo :: Index -> Index -> [Index] Source # enumFromThenTo :: Index -> Index -> Index -> [Index] Source # | |
Generic Index Source # | |
Num Index Source # | |
Read Index Source # | |
Integral Index Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
Real Index Source # | |
Defined in PlutusCore.DeBruijn.Internal toRational :: Index -> Rational Source # | |
Show Index Source # | |
NFData Index Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
Flat Index | |
Eq Index Source # | |
Ord Index Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
Hashable Index Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
Pretty Index Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
type Rep Index Source # | |
Defined in PlutusCore.DeBruijn.Internal |
class HasIndex a where Source #
Instances
HasIndex DeBruijn Source # | |
HasIndex NamedDeBruijn Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
HasIndex NamedTyDeBruijn Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
HasIndex TyDeBruijn Source # | |
Defined in PlutusCore.DeBruijn.Internal |
A term name as a de Bruijn index, without the name string.
Instances
data NamedDeBruijn Source #
A term name as a de Bruijn index.
NamedDeBruijn | |
|
Instances
newtype FakeNamedDeBruijn Source #
A wrapper around NamedDeBruijn
that *must* hold the invariant of name=fakeName
.
We do not export the FakeNamedDeBruijn
constructor: the projection `FND->ND` is safe
but injection `ND->FND` is unsafe, thus they are not isomorphic.
See Note [Why newtype FakeNamedDeBruijn]
Instances
newtype TyDeBruijn Source #
A type name as a de Bruijn index, without the name string.
Instances
newtype NamedTyDeBruijn Source #
A type name as a de Bruijn index.
Instances
data FreeVariableError Source #
We cannot do a correct translation to or from de Bruijn indices if the program is not well-scoped. So we throw an error in such a case.
Instances
class AsFreeVariableError r where Source #
_FreeVariableError :: Prism' r FreeVariableError Source #
_FreeUnique :: Prism' r Unique Source #
_FreeIndex :: Prism' r Index Source #
Instances
AsFreeVariableError FreeVariableError Source # | |
Defined in PlutusCore.DeBruijn.Internal _FreeVariableError :: Prism' FreeVariableError FreeVariableError Source # _FreeUnique :: Prism' FreeVariableError Unique Source # _FreeIndex :: Prism' FreeVariableError Index Source # | |
AsFreeVariableError (Error uni fun ann) Source # | |
Defined in PlutusCore.Error _FreeVariableError :: Prism' (Error uni fun ann) FreeVariableError Source # _FreeUnique :: Prism' (Error uni fun ann) Unique Source # _FreeIndex :: Prism' (Error uni fun ann) Index Source # |
An absolute level in the program.
Instances
Enum Level Source # | |
Defined in PlutusCore.DeBruijn.Internal succ :: Level -> Level Source # pred :: Level -> Level Source # toEnum :: Int -> Level Source # fromEnum :: Level -> Int Source # enumFrom :: Level -> [Level] Source # enumFromThen :: Level -> Level -> [Level] Source # enumFromTo :: Level -> Level -> [Level] Source # enumFromThenTo :: Level -> Level -> Level -> [Level] Source # | |
Num Level Source # | |
Integral Level Source # | |
Defined in PlutusCore.DeBruijn.Internal | |
Real Level Source # | |
Defined in PlutusCore.DeBruijn.Internal toRational :: Level -> Rational Source # | |
Eq Level Source # | |
Ord Level Source # | |
Defined in PlutusCore.DeBruijn.Internal |
During visiting the AST we hold a reader "state" of current level and a current scoping (levelMapping). Invariant-A: the current level is positive and greater than all levels in the levelMapping. Invariant-B: only positive levels are stored in the levelMapping.
LevelInfo | |
|
declareUnique :: (MonadReader LevelInfo m, HasUnique name unique) => name -> m a -> m a Source #
Declare a name with a unique, recording the mapping to a Level
.
declareBinder :: (MonadReader LevelInfo m, MonadQuote m) => m a -> m a Source #
Declares a new binder by assigning a fresh unique to the *current level*.
Maintains invariant-B of LevelInfo
(that only positive levels are stored),
since current level is always positive (invariant-A).
See Note [DeBruijn indices of Binders]
withScope :: MonadReader LevelInfo m => m a -> m a Source #
Enter a scope, incrementing the current Level
by one
Maintains invariant-A (that the current level is positive).
nameToDeBruijn :: MonadReader LevelInfo m => (Unique -> m Index) -> Name -> m NamedDeBruijn Source #
tyNameToDeBruijn :: MonadReader LevelInfo m => (Unique -> m Index) -> TyName -> m NamedTyDeBruijn Source #
deBruijnToName :: MonadReader LevelInfo m => (Index -> m Unique) -> NamedDeBruijn -> m Name Source #
deBruijnToTyName :: MonadReader LevelInfo m => (Index -> m Unique) -> NamedTyDeBruijn -> m TyName Source #
freeIndexThrow :: (AsFreeVariableError e, MonadError e m) => Index -> m Unique Source #
The default handler of throwing an error upon encountering a free debruijn index.
freeIndexAsConsistentLevel :: (MonadReader LevelInfo m, MonadState (Map Level Unique) m, MonadQuote m) => Index -> m Unique Source #
A different implementation of a handler, where "free" debruijn indices do not throw an error but are instead gracefully converted to fresh uniques. These generated uniques remain free; i.e. if the original term was open, it will remain open after applying this handler. These generated free uniques are consistent across the open term (by using a state cache).
freeUniqueThrow :: (AsFreeVariableError e, MonadError e m) => Unique -> m Index Source #
The default handler of throwing an error upon encountering a free name (unique).
runDeBruijnT :: ReaderT LevelInfo m a -> m a Source #
deBruijnInitIndex :: Index Source #
The LamAbs index (for debruijn indices) and the starting level of DeBruijn monad
toFake :: DeBruijn -> FakeNamedDeBruijn Source #
fromFake :: FakeNamedDeBruijn -> DeBruijn Source #