-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | de Bruijn indices and levels -- -- de Bruijn indices and levels for well-scoped terms. -- -- This is "unsafe" (as it uses unsafeCoerce) implementation, but -- it's fast. The API is the same as in debruin-safe package. @package debruijn @version 0.2 module DeBruijn.Ctx -- | Context counts variables, in other words context is just a natural -- number. type Ctx = Nat -- | Empty context is zero. type EmptyCtx = Z -- | And context extension is a successor. type S = 'S type Ctx1 = S EmptyCtx type Ctx2 = S Ctx1 type Ctx3 = S Ctx2 type Ctx4 = S Ctx3 type Ctx5 = S Ctx4 type Ctx6 = S Ctx5 type Ctx7 = S Ctx6 type Ctx8 = S Ctx7 type Ctx9 = S Ctx8 -- | de Bruijn indices for well-scoped terms. module DeBruijn.Internal.Idx -- | de Bruijn indices. -- --
-- >>> IS (IS (IS IZ)) -- 3 --newtype Idx j UnsafeIdx :: Int -> Idx j pattern IZ :: () => m ~ S n => Idx m pattern IS :: () => m ~ S n => Idx n -> Idx m -- | Derive anything from index into empty scope. -- -- Note: don't use EmptyCase on Idx as it doesn't work -- for unsafe representation. absurdIdx :: Idx EmptyCtx -> a -- | Case on Idx. (compare to maybe). unIdx :: a -> (Idx n -> a) -> Idx (S n) -> a -- | Convert index to Int. idxToInt :: Idx ctx -> Int pattern I1 :: () => m ~ S (S n) => Idx m pattern I2 :: () => m ~ S (S (S n)) => Idx m pattern I3 :: () => m ~ S (S (S (S n))) => Idx m pattern I4 :: () => m ~ S (S (S (S (S n)))) => Idx m pattern I5 :: () => m ~ S (S (S (S (S (S n))))) => Idx m pattern I6 :: () => m ~ S (S (S (S (S (S (S n)))))) => Idx m pattern I7 :: () => m ~ S (S (S (S (S (S (S (S n))))))) => Idx m pattern I8 :: () => m ~ S (S (S (S (S (S (S (S (S n)))))))) => Idx m pattern I9 :: () => m ~ S (S (S (S (S (S (S (S (S (S n))))))))) => Idx m instance GHC.Classes.Eq (DeBruijn.Internal.Idx.Idx n) instance GHC.Classes.Ord (DeBruijn.Internal.Idx.Idx n) instance GHC.Show.Show (DeBruijn.Internal.Idx.Idx j) -- | de Bruijn indices for well-scoped terms. module DeBruijn.Idx -- | de Bruijn indices. -- --
-- >>> IS (IS (IS IZ)) -- 3 --data Idx j pattern IZ :: () => m ~ S n => Idx m pattern IS :: () => m ~ S n => Idx n -> Idx m -- | Derive anything from index into empty scope. -- -- Note: don't use EmptyCase on Idx as it doesn't work -- for unsafe representation. absurdIdx :: Idx EmptyCtx -> a -- | Case on Idx. (compare to maybe). unIdx :: a -> (Idx n -> a) -> Idx (S n) -> a -- | Convert index to Int. idxToInt :: Idx ctx -> Int pattern I1 :: () => m ~ S (S n) => Idx m pattern I2 :: () => m ~ S (S (S n)) => Idx m pattern I3 :: () => m ~ S (S (S (S n))) => Idx m pattern I4 :: () => m ~ S (S (S (S (S n)))) => Idx m pattern I5 :: () => m ~ S (S (S (S (S (S n))))) => Idx m pattern I6 :: () => m ~ S (S (S (S (S (S (S n)))))) => Idx m pattern I7 :: () => m ~ S (S (S (S (S (S (S (S n))))))) => Idx m pattern I8 :: () => m ~ S (S (S (S (S (S (S (S (S n)))))))) => Idx m pattern I9 :: () => m ~ S (S (S (S (S (S (S (S (S (S n))))))))) => Idx m module DeBruijn.Internal.Size -- | Term level witness of the size of a context. -- --
-- >>> SZ -- 0 ---- --
-- >>> SS (SS SZ) -- 2 --newtype Size ctx UnsafeSize :: Int -> Size ctx pattern SZ :: () => m ~ EmptyCtx => Size m pattern SS :: () => m ~ S n => Size n -> Size m -- | Unapply SS. Occasionally more useful than pattern matching. unSS :: Size (S ctx) -> Size ctx -- | Convert Size to 'Int. sizeToInt :: Size ctx -> Int pattern S1 :: () => m ~ Ctx1 => Size m pattern S2 :: () => m ~ Ctx2 => Size m pattern S3 :: () => m ~ Ctx3 => Size m pattern S4 :: () => m ~ Ctx4 => Size m pattern S5 :: () => m ~ Ctx5 => Size m pattern S6 :: () => m ~ Ctx6 => Size m pattern S7 :: () => m ~ Ctx7 => Size m pattern S8 :: () => m ~ Ctx8 => Size m pattern S9 :: () => m ~ Ctx9 => Size m instance GHC.Show.Show (DeBruijn.Internal.Size.Size ctx) instance Data.GADT.Internal.GShow DeBruijn.Internal.Size.Size instance GHC.Classes.Eq (DeBruijn.Internal.Size.Size ctx) instance GHC.Classes.Ord (DeBruijn.Internal.Size.Size ctx) instance Data.EqP.EqP DeBruijn.Internal.Size.Size instance Data.OrdP.OrdP DeBruijn.Internal.Size.Size instance Data.GADT.Internal.GEq DeBruijn.Internal.Size.Size instance Data.GADT.Internal.GCompare DeBruijn.Internal.Size.Size instance Data.Type.Equality.TestEquality DeBruijn.Internal.Size.Size module DeBruijn.Internal.Env -- | Environment -- --
-- >>> EmptyEnv :> 'a' :> 'b' -- EmptyEnv :> 'a' :> 'b' --newtype Env ctx a UnsafeEnv :: SkewList a -> Env ctx a pattern EmptyEnv :: () => ctx ~ EmptyCtx => Env ctx a pattern (:>) :: () => ctx ~ S ctx' => Env ctx' a -> a -> Env ctx a infixl 5 :> -- | Lookup in the context. -- --
-- >>> lookupEnv IZ (EmptyEnv :> 'a' :> 'b') -- 'b' --lookupEnv :: Idx ctx -> Env ctx a -> a -- | Size of the environment. -- --
-- >>> sizeEnv (EmptyEnv :> 'a' :> 'b') -- 2 --sizeEnv :: Env n a -> Size n -- | Create Env by creating elements given an Idx. -- --
-- >>> tabulateEnv S4 id -- EmptyEnv :> 3 :> 2 :> 1 :> 0 --tabulateEnv :: Size ctx -> (Idx ctx -> a) -> Env ctx a instance GHC.Base.Functor (DeBruijn.Internal.Env.Env ctx) instance Data.Foldable.Foldable (DeBruijn.Internal.Env.Env ctx) instance Data.Traversable.Traversable (DeBruijn.Internal.Env.Env ctx) instance GHC.Show.Show a => GHC.Show.Show (DeBruijn.Internal.Env.Env ctx a) module DeBruijn.Env -- | Environment -- --
-- >>> EmptyEnv :> 'a' :> 'b' -- EmptyEnv :> 'a' :> 'b' --data Env ctx a pattern EmptyEnv :: () => ctx ~ EmptyCtx => Env ctx a pattern (:>) :: () => ctx ~ S ctx' => Env ctx' a -> a -> Env ctx a infixl 5 :> -- | Lookup in the context. -- --
-- >>> lookupEnv IZ (EmptyEnv :> 'a' :> 'b') -- 'b' --lookupEnv :: Idx ctx -> Env ctx a -> a -- | Size of the environment. -- --
-- >>> sizeEnv (EmptyEnv :> 'a' :> 'b') -- 2 --sizeEnv :: Env n a -> Size n -- | Create Env by creating elements given an Idx. -- --
-- >>> tabulateEnv S4 id -- EmptyEnv :> 3 :> 2 :> 1 :> 0 --tabulateEnv :: Size ctx -> (Idx ctx -> a) -> Env ctx a module DeBruijn.Internal.Add -- | Add n m p is an evidence that n + m = p. -- -- Useful when you have an arity n thing and need to extend a -- context ctx with: Add n ctx ctx'. -- -- Using a type representing a graph of a type function is often more -- convenient than defining type-family to begin with. newtype Add n m p UnsafeAdd :: Int -> Add n m p pattern AZ :: () => (n ~ EmptyCtx, m ~ p) => Add n m p pattern AS :: () => (n ~ S n', p ~ S p') => Add n' m p' -> Add n m p addToInt :: Add n m p -> Int addToSize :: Add n m p -> Size n -- | Add n to some context ctx. -- --
-- >>> adding (SS (SS SZ)) -- Some 2 --adding :: Size n -> Some (Add n ctx) -- |
-- n + 0 ≡ 0 --rzeroAdd :: Size n -> Add n EmptyCtx n -- |
-- n + 0 ≡ m → n ≡ m --unrzeroAdd :: Add n EmptyCtx m -> n :~: m -- |
-- 0 + n ≡ 0 --lzeroAdd :: Size n -> Add EmptyCtx n n -- |
-- 0 + n ≡ m → n ≡ m --unlzeroAdd :: Add EmptyCtx n m -> n :~: m -- |
-- n + m ≡ p → n + S m ≡ S p --rsuccAdd :: Add n m p -> Add n (S m) (S p) -- |
-- n + S m ≡ S p → n + m ≡ p --unrsuccAdd :: Add n (S m) (S p) -> Add n m p -- |
-- n + m ≡ p → S n + m ≡ S p --lsuccAdd :: Add n m p -> Add (S n) m (S p) -- |
-- S n + m ≡ S p → n + m ≡ p --unlsuccAdd :: Add (S n) m (S p) -> Add n m p -- |
-- n + S m ≡ p → S n + m ≡ p --swapAdd :: Add n (S m) p -> Add (S n) m p -- |
-- S n + m ≡ p → n + S m ≡ p --unswapAdd :: Add (S n) m p -> Add n (S m) p instance GHC.Show.Show (DeBruijn.Internal.Add.Add n m p) instance Data.GADT.Internal.GShow (DeBruijn.Internal.Add.Add n m) module DeBruijn.Add -- | Add n m p is an evidence that n + m = p. -- -- Useful when you have an arity n thing and need to extend a -- context ctx with: Add n ctx ctx'. -- -- Using a type representing a graph of a type function is often more -- convenient than defining type-family to begin with. data Add n m p pattern AZ :: () => (n ~ EmptyCtx, m ~ p) => Add n m p pattern AS :: () => (n ~ S n', p ~ S p') => Add n' m p' -> Add n m p addToInt :: Add n m p -> Int addToSize :: Add n m p -> Size n -- | Add n to some context ctx. -- --
-- >>> adding (SS (SS SZ)) -- Some 2 --adding :: Size n -> Some (Add n ctx) -- |
-- n + 0 ≡ 0 --rzeroAdd :: Size n -> Add n EmptyCtx n -- |
-- n + 0 ≡ m → n ≡ m --unrzeroAdd :: Add n EmptyCtx m -> n :~: m -- |
-- 0 + n ≡ 0 --lzeroAdd :: Size n -> Add EmptyCtx n n -- |
-- 0 + n ≡ m → n ≡ m --unlzeroAdd :: Add EmptyCtx n m -> n :~: m -- |
-- n + m ≡ p → n + S m ≡ S p --rsuccAdd :: Add n m p -> Add n (S m) (S p) -- |
-- n + S m ≡ S p → n + m ≡ p --unrsuccAdd :: Add n (S m) (S p) -> Add n m p -- |
-- n + m ≡ p → S n + m ≡ S p --lsuccAdd :: Add n m p -> Add (S n) m (S p) -- |
-- S n + m ≡ S p → n + m ≡ p --unlsuccAdd :: Add (S n) m (S p) -> Add n m p -- |
-- n + S m ≡ p → S n + m ≡ p --swapAdd :: Add n (S m) p -> Add (S n) m p -- |
-- S n + m ≡ p → n + S m ≡ p --unswapAdd :: Add (S n) m p -> Add n (S m) p module DeBruijn.Lte -- | Lte ctx ctx' is evidence that ctx' is smaller -- than of ctx, less-than-or-equal, and produced -- by simple skipping only, i.e. nothing is inserted into ctx, -- only appended to the end. data Lte ctx ctx' [LZ] :: Lte ctx ctx [LS] :: !Lte ctx ctx' -> Lte ctx (S ctx') -- | de Bruijn levels for well-scoped terms. module DeBruijn.Internal.Lvl -- | de Bruijn levels. newtype Lvl ctx UnsafeLvl :: Int -> Lvl ctx -- | Convert level to index. -- --
-- >>> lvlToIdx S2 (lvlZ S1) -- 0 --lvlToIdx :: Size ctx -> Lvl ctx -> Idx ctx idxToLvl :: Size ctx -> Idx ctx -> Lvl ctx -- | Last level. -- --
-- >>> lvlZ S1 -- 1 ---- --
-- >>> lvlZ S5 -- 5 --lvlZ :: Size ctx -> Lvl (S ctx) -- | Sink Lvl into a larger context. -- --
-- >>> sinkLvl (lvlZ S3) -- 3 ---- --
-- >>> sink (lvlZ S3) -- 3 ---- --
-- >>> mapLvl (LS LZ) (lvlZ S3) -- 3 --sinkLvl :: Lvl n -> Lvl (S n) -- | Sinkable terms can be weakened (sunk) cheaply. class Sinkable t mapLvl :: Sinkable t => Lte ctx ctx' -> t ctx -> t ctx' -- | Sink term. sink :: Sinkable t => t ctx -> t (S ctx) -- | Essentially fmap sink mapSink :: (Functor f, Sinkable t) => f (t ctx) -> f (t (S ctx)) -- | Sink term from empty context to a context of given size. sinkSize :: Sinkable t => Size ctx -> t EmptyCtx -> t ctx -- | Essentially fmap . sinkSize mapSinkSize :: (Functor f, Sinkable t) => Size ctx -> f (t EmptyCtx) -> f (t ctx) sinkAdd :: Sinkable t => Add n ctx ctx' -> t ctx -> t ctx' mapSinkAdd :: (Functor f, Sinkable t) => Add n ctx ctx' -> f (t ctx) -> f (t ctx') instance GHC.Classes.Ord (DeBruijn.Internal.Lvl.Lvl ctx) instance GHC.Classes.Eq (DeBruijn.Internal.Lvl.Lvl ctx) instance DeBruijn.Internal.Lvl.Sinkable DeBruijn.Internal.Lvl.Lvl instance DeBruijn.Internal.Lvl.Sinkable Data.Proxy.Proxy instance GHC.Show.Show (DeBruijn.Internal.Lvl.Lvl ctx) module DeBruijn.Lvl -- | de Bruijn levels. data Lvl ctx -- | Convert level to index. -- --
-- >>> lvlToIdx S2 (lvlZ S1) -- 0 --lvlToIdx :: Size ctx -> Lvl ctx -> Idx ctx -- | Last level. -- --
-- >>> lvlZ S1 -- 1 ---- --
-- >>> lvlZ S5 -- 5 --lvlZ :: Size ctx -> Lvl (S ctx) idxToLvl :: Size ctx -> Idx ctx -> Lvl ctx -- | Sinkable terms can be weakened (sunk) cheaply. class Sinkable t mapLvl :: Sinkable t => Lte ctx ctx' -> t ctx -> t ctx' -- | Sink term. sink :: Sinkable t => t ctx -> t (S ctx) -- | Sink term from empty context to a context of given size. sinkSize :: Sinkable t => Size ctx -> t EmptyCtx -> t ctx sinkAdd :: Sinkable t => Add n ctx ctx' -> t ctx -> t ctx' -- | Essentially fmap sink mapSink :: (Functor f, Sinkable t) => f (t ctx) -> f (t (S ctx)) -- | Essentially fmap . sinkSize mapSinkSize :: (Functor f, Sinkable t) => Size ctx -> f (t EmptyCtx) -> f (t ctx) mapSinkAdd :: (Functor f, Sinkable t) => Add n ctx ctx' -> f (t ctx) -> f (t ctx') module DeBruijn.Size -- | Term level witness of the size of a context. -- --
-- >>> SZ -- 0 ---- --
-- >>> SS (SS SZ) -- 2 --data Size ctx pattern SZ :: () => m ~ EmptyCtx => Size m pattern SS :: () => m ~ S n => Size n -> Size m -- | Unapply SS. Occasionally more useful than pattern matching. unSS :: Size (S ctx) -> Size ctx -- | Convert Size to 'Int. sizeToInt :: Size ctx -> Int pattern S1 :: () => m ~ Ctx1 => Size m pattern S2 :: () => m ~ Ctx2 => Size m pattern S3 :: () => m ~ Ctx3 => Size m pattern S4 :: () => m ~ Ctx4 => Size m pattern S5 :: () => m ~ Ctx5 => Size m pattern S6 :: () => m ~ Ctx6 => Size m pattern S7 :: () => m ~ Ctx7 => Size m pattern S8 :: () => m ~ Ctx8 => Size m pattern S9 :: () => m ~ Ctx9 => Size m module DeBruijn.Wk -- | Weakenings, order preserving embeddings. -- -- Wk n m could be represented as m bit field with -- popCount of n. -- -- Constructor names make sense when you look at the implementation of -- weakenEnv. -- -- Note: usually 'ViewWk is defined as -- --
-- data Wk ctx ctx' where -- WkNil :: Wk EmptyCtx EmptyCtx -- KeepWk :: Wk ctx ctx' -> Wk (S ctx) (S ctx') -- SkipWk :: Wk ctx ctx' -> Wk ctx (S ctx') ---- -- However that representation doesn't allow to make wkId :: -- 'ViewWk ctx ctx without knowing the size of context. Therefore we -- morally use a representation closer to -- --
-- data Wk ctx ctx' where -- IdWk :: Wk ctx ctx -- KeepWk :: Wk ctx ctx' -> Wk (S ctx) (S ctx') -- SkipWk :: Wk ctx ctx' -> Wk ctx (S ctx') ---- -- But we keep an invariant that identity weakenings are always -- represented by IdWk. -- --
-- >>> KeepWk IdWk -- IdWk ---- -- And KeepWk pattern doesn't match on identity weakenings. -- --
-- >>> case IdWk :: Wk Ctx2 Ctx2 of { KeepWk _ -> "keep"; SkipWk _ -> "skip"; IdWk -> "id" } :: String
-- "id"
--
data Wk ctx ctx'
[IdWk] :: Wk ctx ctx
pattern SkipWk :: () => b ~ S b' => Wk a b' -> Wk a b
pattern KeepWk :: () => (a ~ S a', b ~ S b') => Wk a' b' -> Wk a b
-- | Weaken by one. wk1 = SkipWk IdWk.
wk1 :: Wk ctx (S ctx)
-- | Weakening composition.
compWk :: Wk a b -> Wk b c -> Wk a c
-- | Weaken Idx, i.e. map index from smaller to larger context.
--
-- -- >>> IS IZ -- 1 ---- --
-- >>> weakenIdx wk1 (IS IZ) -- 2 --weakenIdx :: Wk ctx ctx' -> Idx ctx -> Idx ctx' -- | Contract Idx, i.e. map index from larger to smaller context. -- --
-- >>> contractIdx wk1 (IS IZ) -- Just 0 ---- --
-- >>> contractIdx wk1 IZ -- Nothing ---- --
-- >>> contractIdx (SkipWk (KeepWk wk1)) <$> [IZ, IS IZ, IS (IS IZ), IS (IS IZ), IS (IS (IS IZ)), IS (IS (IS (IS IZ)))] -- [Nothing,Just 0,Nothing,Nothing,Just 1,Just 2] --contractIdx :: Wk ctx ctx' -> Idx ctx' -> Maybe (Idx ctx) -- | Weaken Size. weakenSize :: Wk ctx ctx' -> Size ctx -> Size ctx' contractSize :: Wk ctx ctx' -> Size ctx' -> Size ctx -- | Contract Env i.e. drop elements from larger context. -- -- This function explains the KeepWk and SkipWk constructor -- names: -- --
-- >>> weakenEnv (IdWk & SkipWk & KeepWk) (EmptyEnv :> 'a' :> 'b' :> 'c' :> 'd' :> 'e') -- EmptyEnv :> 'a' :> 'b' :> 'c' :> 'e' --weakenEnv :: Wk ctx ctx' -> Env ctx' a -> Env ctx a -- | setWeakenEnv and weakenEnv together form a lens. -- --
-- >>> setWeakenEnv (IdWk & SkipWk & KeepWk) (EmptyEnv :> 'a' :> 'b') (EmptyEnv :> 'x' :> 'y' :> 'z') -- EmptyEnv :> 'a' :> 'y' :> 'b' --setWeakenEnv :: Wk ctx ctx' -> Env ctx a -> Env ctx' a -> Env ctx' a -- | Setter made from setWeakenEnv and weakenEnv. -- --
-- >>> overWeakenEnv (IdWk & SkipWk & KeepWk) (fmap toUpper) (EmptyEnv :> 'a' :> 'x' :> 'y' :> 'z') -- EmptyEnv :> 'A' :> 'X' :> 'y' :> 'Z' --overWeakenEnv :: Wk ctx ctx' -> (Env ctx a -> Env ctx a) -> Env ctx' a -> Env ctx' a instance GHC.Classes.Eq (DeBruijn.Wk.Wk ctx ctx') instance GHC.Classes.Eq (DeBruijn.Wk.Wk1 ctx ctx') instance GHC.Show.Show (DeBruijn.Wk.Wk ctx ctx') module DeBruijn.Ren -- | Renamings are mappings of de Bruijn indices. -- -- One possible representation is just Idx ctx -> Idx ctx', -- but using Env makes this representation inspectable and -- (hopefully) makes renameIdx perform better. -- -- On the other hand, idRen requires Size ctx. -- However this isn't an issue, as either there is Size or using -- Wk is an option. newtype Ren ctx ctx' MkRen :: Env ctx (Idx ctx') -> Ren ctx ctx' -- | Rename de Bruijn index. renameIdx :: Ren ctx ctx' -> Idx ctx -> Idx ctx' -- | Lift renaming (used when going under a binder). keepRen :: Ren ctx ctx' -> Ren (S ctx) (S ctx') skipRen :: Ren ctx ctx' -> Ren ctx (S ctx') -- | It's simple to have no indices in any context. absurdRen :: Ren EmptyCtx ctx -- | Convert Wk to Ren. -- -- Note post and precompositions won't need Size. wkToRen :: Size ctx -> Wk ctx ctx' -> Ren ctx ctx' -- | Identity renaming. idRen :: Size ctx -> Ren ctx ctx -- | Renaming composition. compRen :: Ren ctx ctx' -> Ren ctx' ctx'' -> Ren ctx ctx'' newtype RenA f ctx ctx' MkRenA :: Env ctx (f (Idx ctx')) -> RenA f ctx ctx' renameIdxA :: RenA f ctx ctx' -> Idx ctx -> f (Idx ctx') -- | Lift renaming (used when going under a binder). keepRenA :: Applicative f => RenA f ctx ctx' -> RenA f (S ctx) (S ctx') unusedIdx :: Size ctx -> RenA Maybe (S ctx) ctx -- | IdxMapping generalizes over various index mappings, also -- effectful ones. class Applicative f => IdxMapping f t | t -> f -- | IdxMapping action. mapIdx :: IdxMapping f t => t ctx ctx' -> Idx ctx -> f (Idx ctx') -- | keep is often called lift, but we stick with Wk -- terminology. One benefit is that the name keep is less likely -- to clash. keep :: IdxMapping f t => t ctx ctx' -> t (S ctx) (S ctx') -- | Compose weakening with an index mapping. -- -- This is useful when you have explicit weakening in your terms. (a -- similar idea as in bound's Scope possibly lifting -- whole term). weakenIdxMapping :: IdxMapping f t => Wk ctx ctx' -> t ctx' ctx'' -> t ctx ctx'' -- | keep IdxMapping arity times. keepAdd :: IdxMapping f m => Add arity ctxA ctxA' -> m ctxA ctxB -> (forall ctxB'. Add arity ctxB ctxB' -> m ctxA' ctxB' -> r) -> r -- | Renameble things. -- -- For most terms it's enough to define a single traversal: an instance -- of RenamebleA type-class, and then define Renameble -- as: -- --
-- instance Renameble Term where rename = defaultRename; weaken = defaultWeaken --class Weaken t weaken :: Weaken t => Wk n m -> t n -> t m class Weaken t => Rename t rename :: Rename t => Ren n m -> t n -> t m -- | Effectful renamings. -- -- An common example is checking whether a binding is used: -- --
-- Just t' <- renameA unusedIdx t --class Rename t => RenameA t renameA :: forall f ctx ctx'. (RenameA t, Applicative f) => RenA f ctx ctx' -> t ctx -> f (t ctx') -- | Generic renaming of a term t using any IdxMapping. grename :: forall m f ctx ctx'. (RenameA t, IdxMapping f m) => m ctx ctx' -> t ctx -> f (t ctx') -- | rename implementation using grename. defaultRename :: forall t n m. RenameA t => Ren n m -> t n -> t m -- | weaken implementation using grename. defaultWeaken :: forall t n m. RenameA t => Wk n m -> t n -> t m instance DeBruijn.Ren.RenameA Data.Proxy.Proxy instance DeBruijn.Ren.RenameA DeBruijn.Internal.Idx.Idx instance DeBruijn.Ren.Rename Data.Proxy.Proxy instance DeBruijn.Ren.Rename DeBruijn.Internal.Idx.Idx instance DeBruijn.Ren.Rename (DeBruijn.Ren.Ren n) instance DeBruijn.Ren.Weaken Data.Proxy.Proxy instance DeBruijn.Ren.Weaken DeBruijn.Internal.Idx.Idx instance DeBruijn.Ren.Weaken (DeBruijn.Ren.Ren n) instance DeBruijn.Ren.IdxMapping Data.Functor.Identity.Identity DeBruijn.Wk.Wk instance DeBruijn.Ren.IdxMapping Data.Functor.Identity.Identity DeBruijn.Ren.Ren instance GHC.Base.Applicative f => DeBruijn.Ren.IdxMapping f (DeBruijn.Ren.RenA f) module DeBruijn.Sub -- | Substitutions. newtype Sub t ctx ctx' MkSub :: Env ctx (t ctx') -> Sub t ctx ctx' unSub :: Sub t ctx ctx' -> Env ctx (t ctx') -- | Substitute index. substIdx :: Sub t ctx ctx' -> Idx ctx -> t ctx' -- | Substitution from empty context. emptySub :: Sub t EmptyCtx ctx' snocSub :: Sub t ctx ctx' -> t ctx' -> Sub t (S ctx) ctx' keepSub :: (Rename t, Var t) => Sub t ctx ctx' -> Sub t (S ctx) (S ctx') -- | Precompose Sub with weakening. weakenSub :: Wk ctx ctx' -> Sub t ctx' ctx'' -> Sub t ctx ctx'' nameMe :: Rename t => Sub t ctx ctx' -> Wk ctx' ctx'' -> Sub t ctx ctx'' -- | Identity substitution idSub :: Var t => Size ctx -> Sub t ctx ctx -- | Substitution composition. compSub :: Subst t => Sub t ctx ctx' -> Sub t ctx' ctx'' -> Sub t ctx ctx'' -- | Terms which contain indices as variables. class Var t var :: Var t => Idx ctx -> t ctx -- | Terms which we can subsitute into. class Var t => Subst t subst :: Subst t => Sub t ctx ctx' -> t ctx -> t ctx' instance DeBruijn.Sub.Subst Data.Proxy.Proxy instance DeBruijn.Sub.Subst DeBruijn.Internal.Idx.Idx instance DeBruijn.Sub.Var Data.Proxy.Proxy instance DeBruijn.Sub.Var DeBruijn.Internal.Idx.Idx module DeBruijn -- | Weaken closed term to arbitrary context. -- -- Note: this has different requirements than sinkSize. weakenUsingSize :: Rename t => Size ctx -> t EmptyCtx -> t ctx