-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/
-- | Fill-in-the-blanks - A library factoring out substitution from ASTs
--
-- Please see the README on GitHub at
-- https://github.com/ejconlon/blanks#readme
@package blanks
@version 0.4.0
module Blanks.Located
-- | Because we defined a unique left adjoint, we have to define the unique
-- right.
newtype Colocated l a
Colocated :: Reader l a -> Colocated l a
[unColocated] :: Colocated l a -> Reader l a
-- | This is basically the Env comonad, but with the env strict.
-- It's also basically the Writer monad in certain contexts. We
-- define a new, non-transforming datatype so we can pattern-match.
data Located l a
Located :: !l -> a -> Located l a
[_locatedLoc] :: Located l a -> !l
[_locatedVal] :: Located l a -> a
askColocated :: Colocated l l
colocated :: (l -> a) -> Colocated l a
runColocated :: Colocated l a -> l -> a
instance Data.Functor.Rep.Representable (Blanks.Located.Colocated l)
instance Control.Monad.Reader.Class.MonadReader l (Blanks.Located.Colocated l)
instance GHC.Base.Monad (Blanks.Located.Colocated l)
instance GHC.Base.Applicative (Blanks.Located.Colocated l)
instance GHC.Base.Functor (Blanks.Located.Colocated l)
instance Data.Traversable.Traversable (Blanks.Located.Located l)
instance Data.Foldable.Foldable (Blanks.Located.Located l)
instance GHC.Base.Functor (Blanks.Located.Located l)
instance (GHC.Show.Show l, GHC.Show.Show a) => GHC.Show.Show (Blanks.Located.Located l a)
instance (GHC.Classes.Eq l, GHC.Classes.Eq a) => GHC.Classes.Eq (Blanks.Located.Located l a)
instance Data.Distributive.Distributive (Blanks.Located.Colocated l)
instance Data.Functor.Adjunction.Adjunction (Blanks.Located.Located l) (Blanks.Located.Colocated l)
instance GHC.Base.Monoid l => GHC.Base.Applicative (Blanks.Located.Located l)
instance GHC.Base.Monoid l => GHC.Base.Monad (Blanks.Located.Located l)
instance GHC.Base.Monoid l => Control.Monad.Writer.Class.MonadWriter l (Blanks.Located.Located l)
module Blanks.Name
-- | Name is compared on value only, allowing you to define and use
-- things like NameOnly in your BlankInfo values to make
-- alpha-equivalent terms structurally (Eq) equivalent.
data Name n a
Name :: n -> a -> Name n a
[_nameKey] :: Name n a -> n
[_nameValue] :: Name n a -> a
type NameOnly n = Name n ()
pattern NameOnly :: n -> NameOnly n
instance Data.Traversable.Traversable (Blanks.Name.Name n)
instance Data.Foldable.Foldable (Blanks.Name.Name n)
instance GHC.Base.Functor (Blanks.Name.Name n)
instance (GHC.Show.Show n, GHC.Show.Show a) => GHC.Show.Show (Blanks.Name.Name n a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Blanks.Name.Name n a)
module Blanks.NatNewtype
-- | A "natural isomorphism" between two functors, like exists derivably
-- between newtyped functors and their wrapped types. The functional
-- dependency requires that g be the newtype and m the
-- wrapped type.
class (forall a. Coercible (m a) (g a), forall a. Coercible (g a) (m a)) => NatNewtype (m :: Type -> Type) (g :: Type -> Type) | g -> m
-- | Coerce from the newtype to the wrapped type.
natNewtypeFrom :: NatNewtype m g => g a -> m a
-- | Coerce from the wrapped type to the newtype.
natNewtypeTo :: NatNewtype m g => m a -> g a
module Blanks.Sub
-- | Errors that happen in the course of instantiation, thrown by
-- blankApply and related functions.
data SubError
ApplyError :: !Int -> !Int -> SubError
UnboundError :: !Int -> SubError
NonBinderError :: SubError
-- | Some monadic context that lets you throw a SubError. Exists to
-- let you rethrow to a more convenient context rather than pattern
-- maching.
class ThrowSub m
throwSub :: ThrowSub m => SubError -> m a
rethrowSub :: (Applicative m, ThrowSub m) => Either SubError a -> m a
instance GHC.Show.Show Blanks.Sub.SubError
instance GHC.Classes.Eq Blanks.Sub.SubError
instance Blanks.Sub.ThrowSub (Data.Either.Either Blanks.Sub.SubError)
instance Blanks.Sub.ThrowSub GHC.Types.IO
instance GHC.Exception.Type.Exception Blanks.Sub.SubError
-- | Internals. You will probably never need these.
module Blanks.UnderScope
data BinderScope n e
BinderScope :: !Int -> !n -> e -> BinderScope n e
[binderScopeArity] :: BinderScope n e -> !Int
[binderScopeInfo] :: BinderScope n e -> !n
[binderScopeBody] :: BinderScope n e -> e
newtype BoundScope
BoundScope :: Int -> BoundScope
[unBoundScope] :: BoundScope -> Int
newtype EmbedScope f e
EmbedScope :: f e -> EmbedScope f e
[unEmbedScope] :: EmbedScope f e -> f e
newtype FreeScope a
FreeScope :: a -> FreeScope a
[unFreeScope] :: FreeScope a -> a
data UnderScope n f e a
UnderBoundScope :: !BoundScope -> UnderScope n f e a
UnderFreeScope :: !FreeScope a -> UnderScope n f e a
UnderBinderScope :: !BinderScope n e -> UnderScope n f e a
UnderEmbedScope :: !EmbedScope f e -> UnderScope n f e a
data UnderScopeFold n f e a r
UnderScopeFold :: (BoundScope -> r) -> (FreeScope a -> r) -> (BinderScope n e -> r) -> (EmbedScope f e -> r) -> UnderScopeFold n f e a r
[usfBound] :: UnderScopeFold n f e a r -> BoundScope -> r
[usfFree] :: UnderScopeFold n f e a r -> FreeScope a -> r
[usfBinder] :: UnderScopeFold n f e a r -> BinderScope n e -> r
[usfEmbed] :: UnderScopeFold n f e a r -> EmbedScope f e -> r
pattern UnderScopeBound :: Int -> UnderScope n f e a
pattern UnderScopeFree :: a -> UnderScope n f e a
pattern UnderScopeBinder :: Int -> n -> e -> UnderScope n f e a
pattern UnderScopeEmbed :: f e -> UnderScope n f e a
underScopeFold :: UnderScopeFold n f e a r -> UnderScope n f e a -> r
underScopeShift :: Functor f => (Int -> Int -> e -> e) -> Int -> Int -> UnderScope n f e a -> UnderScope n f e a
instance GHC.Base.Functor (Blanks.UnderScope.UnderScopeFold n f e a)
instance GHC.Base.Functor (Blanks.UnderScope.UnderScope n f e)
instance (GHC.Show.Show a, GHC.Show.Show n, GHC.Show.Show e, GHC.Show.Show (f e)) => GHC.Show.Show (Blanks.UnderScope.UnderScope n f e a)
instance (GHC.Classes.Eq a, GHC.Classes.Eq n, GHC.Classes.Eq e, GHC.Classes.Eq (f e)) => GHC.Classes.Eq (Blanks.UnderScope.UnderScope n f e a)
instance GHC.Base.Functor f => GHC.Base.Functor (Blanks.UnderScope.EmbedScope f)
instance GHC.Show.Show (f e) => GHC.Show.Show (Blanks.UnderScope.EmbedScope f e)
instance GHC.Classes.Eq (f e) => GHC.Classes.Eq (Blanks.UnderScope.EmbedScope f e)
instance Data.Traversable.Traversable (Blanks.UnderScope.BinderScope n)
instance Data.Foldable.Foldable (Blanks.UnderScope.BinderScope n)
instance GHC.Base.Functor (Blanks.UnderScope.BinderScope n)
instance (GHC.Show.Show n, GHC.Show.Show e) => GHC.Show.Show (Blanks.UnderScope.BinderScope n e)
instance (GHC.Classes.Eq n, GHC.Classes.Eq e) => GHC.Classes.Eq (Blanks.UnderScope.BinderScope n e)
instance Data.Traversable.Traversable Blanks.UnderScope.FreeScope
instance Data.Foldable.Foldable Blanks.UnderScope.FreeScope
instance GHC.Base.Functor Blanks.UnderScope.FreeScope
instance GHC.Show.Show a => GHC.Show.Show (Blanks.UnderScope.FreeScope a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Blanks.UnderScope.FreeScope a)
instance GHC.Show.Show Blanks.UnderScope.BoundScope
instance GHC.Classes.Eq Blanks.UnderScope.BoundScope
instance GHC.Base.Functor f => Data.Bifunctor.Bifunctor (Blanks.UnderScope.UnderScope n f)
instance Data.Foldable.Foldable f => Data.Bifoldable.Bifoldable (Blanks.UnderScope.UnderScope n f)
instance Data.Traversable.Traversable f => Data.Bitraversable.Bitraversable (Blanks.UnderScope.UnderScope n f)
-- | Internals. You'd need to newtype ScopeW to implement your own
-- Blank.
module Blanks.ScopeW
type ScopeC t u n f g = (Adjunction t u, Applicative u, Functor f, NatNewtype (ScopeW t n f g) g)
newtype ScopeW t n f g a
ScopeW :: t (UnderScope n f (g a) a) -> ScopeW t n f g a
[unScopeW] :: ScopeW t n f g a -> t (UnderScope n f (g a) a)
type ScopeWRawFold n f g a r = UnderScopeFold n f (g a) a r
type ScopeWFold u n f g a r = ScopeWRawFold n f g a (u r)
scopeWFree :: ScopeC t u n f g => a -> u (g a)
scopeWEmbed :: ScopeC t u n f g => f (g a) -> u (g a)
scopeWAbstract :: (ScopeC t u n f g, Eq a) => n -> Seq a -> g a -> u (g a)
scopeWUnAbstract :: ScopeC t u n f g => Seq a -> g a -> g a
scopeWInstantiate :: ScopeC t u n f g => Seq (u (g a)) -> g a -> g a
scopeWApply :: ScopeC t u n f g => Seq (u (g a)) -> g a -> Either SubError (g a)
scopeWBind :: ScopeC t u n f g => (a -> u (g b)) -> g a -> g b
scopeWBindOpt :: ScopeC t u n f g => (a -> Maybe (u (g a))) -> g a -> g a
scopeWLift :: (ScopeC t u n f g, Monad u, Traversable f) => f a -> u (g a)
scopeWRawFold :: (NatNewtype (ScopeW t n f g) g, Functor t) => ScopeWRawFold n f g a r -> g a -> t r
scopeWFold :: (NatNewtype (ScopeW t n f g) g, Adjunction t u) => ScopeWFold u n f g a r -> g a -> r
scopeWLiftAnno :: (NatNewtype (ScopeW t n f g) g, Functor t) => t a -> g a
scopeWHoistAnno :: (NatNewtype (ScopeW t n f g) g, NatNewtype (ScopeW w n f h) h, Functor t, Functor w, Functor f) => (forall x. t x -> w x) -> g a -> h a
scopeWMapAnno :: ScopeC t u n f g => (t a -> t b) -> g a -> g b
instance GHC.Classes.Eq (t (Blanks.UnderScope.UnderScope n f (g a) a)) => GHC.Classes.Eq (Blanks.ScopeW.ScopeW t n f g a)
instance GHC.Show.Show (t (Blanks.UnderScope.UnderScope n f (g a) a)) => GHC.Show.Show (Blanks.ScopeW.ScopeW t n f g a)
instance (GHC.Base.Functor t, GHC.Base.Functor f, GHC.Base.Functor g) => GHC.Base.Functor (Blanks.ScopeW.ScopeW t n f g)
instance (Data.Foldable.Foldable t, Data.Foldable.Foldable f, Data.Foldable.Foldable g) => Data.Foldable.Foldable (Blanks.ScopeW.ScopeW t n f g)
instance (Data.Traversable.Traversable t, Data.Traversable.Traversable f, Data.Traversable.Traversable g) => Data.Traversable.Traversable (Blanks.ScopeW.ScopeW t n f g)
module Blanks.Interface
-- | Indicates that g is a "scope" functor we can use for
-- name-binding. (Behind-the-scenes, g must be a newtype wrapper
-- over the ScopeW datatype.) Most of the time you will use
-- Scope or LocScope directly, which are instances of
-- this class.
--
-- We use the pair of adjoint functors indexed by g to shift the
-- burden of operating in context where it is more convenient. For
-- example, LocScope uses a pair of functors that are
-- essentially Env and Reader. The left adjoint
-- Env lets us annotate every level of our expression tree with
-- a location, and the right adjoint Reader informs us of that
-- location so we don't have to make one up out of thin air!
--
-- Scope uses the pair of functors Identity and
-- Identity, which means there is no ability to store any
-- additional information in the tree, but there's also no additional
-- burden to provide that information.
class (Adjunction (BlankLeft g) (BlankRight g), Applicative (BlankRight g), Functor (BlankFunctor g), NatNewtype (ScopeW (BlankLeft g) (BlankInfo g) (BlankFunctor g) g) g) => Blank (g :: Type -> Type)
-- | The left adjoint functor used by g.
type family BlankLeft (g :: Type -> Type) :: Type -> Type
-- | The right adjoint functor used by g
type family BlankRight (g :: Type -> Type) :: Type -> Type
-- | The binder info used by g.
type family BlankInfo (g :: Type -> Type) :: Type
-- | The expression functor used by g.
type family BlankFunctor (g :: Type -> Type) :: Type -> Type
type BlankRawFold (g :: Type -> Type) (a :: Type) (r :: Type) = UnderScopeFold (BlankInfo g) (BlankFunctor g) (g a) a r
type BlankFold (g :: Type -> Type) (a :: Type) (r :: Type) = BlankRawFold g a (BlankRight g r)
-- | A pair of Blank functors that index the same info and embedded
-- functors. Used to change adjoint functors.
type BlankPair g h = (Blank g, Blank h, BlankInfo g ~ BlankInfo h, BlankFunctor g ~ BlankFunctor h)
-- | Creates a free variable in context.
blankFree :: Blank g => a -> BlankRight g (g a)
-- | Embeds an expression functor in context.
blankEmbed :: Blank g => BlankFunctor g (g a) -> BlankRight g (g a)
-- | Binds free variables in an expression and returns a binder.
blankAbstract :: (Blank g, Eq a) => BlankInfo g -> Seq a -> g a -> BlankRight g (g a)
-- | blankAbstract for a single argument.
blankAbstract1 :: (Blank g, Eq a) => BlankInfo g -> a -> g a -> BlankRight g (g a)
-- | Un-bind free variables in an expression. Basically the inverse of
-- blankAbstract. Take care to match the arity of the binder!
-- (blankApply is safer.)
blankUnAbstract :: Blank g => Seq a -> g a -> g a
blankUnAbstract1 :: Blank g => a -> g a -> g a
-- | Instantiate the bound variables in an expression with other
-- expressions. Take care to match the arity of the binder!
-- (blankApply is safer.)
blankInstantiate :: Blank g => Seq (BlankRight g (g a)) -> g a -> g a
-- | blankInstantiate for a single argument.
blankInstantiate1 :: Blank g => BlankRight g (g a) -> g a -> g a
-- | Instantiates the bound variables in an expression with other
-- expressions. Throws errors on mismatched arity, non binder expression,
-- unbound vars, etc. A version of blankInstantiate that fails
-- loudly instead of silently!
blankApply :: Blank g => Seq (BlankRight g (g a)) -> g a -> Either SubError (g a)
-- | blankApply for a single argument.
blankApply1 :: Blank g => BlankRight g (g a) -> g a -> Either SubError (g a)
-- | A ThrowSub version of blankApply.
blankApplyThrow :: (Blank g, ThrowSub m, Applicative m) => Seq (BlankRight g (g a)) -> g a -> m (g a)
-- | A ThrowSub version of blankApply1.
blankApply1Throw :: (Blank g, ThrowSub m, Applicative m) => BlankRight g (g a) -> g a -> m (g a)
-- | Substitution as a kind of monadic bind.
blankBind :: Blank g => (a -> BlankRight g (g b)) -> g a -> g b
-- | Optional substitution as another kind of monadic bind.
blankBindOpt :: Blank g => (a -> Maybe (BlankRight g (g a))) -> g a -> g a
-- | Lift an expression functor into the scope functor.
blankLift :: (Blank g, Monad (BlankRight g), Traversable (BlankFunctor g)) => BlankFunctor g a -> BlankRight g (g a)
-- | Pattern match all cases of the scope functor.
blankRawFold :: Blank g => BlankRawFold g a r -> g a -> BlankLeft g r
-- | Pattern match all cases of the scope functor, and eliminate the
-- adjoints.
blankFold :: Blank g => BlankFold g a r -> g a -> r
-- | Lift a value of your left adjoint functor (annotating the tree) into
-- your scope functor.
blankLiftAnno :: Blank g => BlankLeft g a -> g a
-- | Apply a natural transformation to your left adjoint functor
-- (annotating the tree) to change scope functors.
blankHoistAnno :: BlankPair g h => (forall x. BlankLeft g x -> BlankLeft h x) -> g a -> h a
-- | Apply a function to the free variables in scope in the context of the
-- left adjoint functor. (Allows you to read annotations when fmapping.)
blankMapAnno :: Blank g => (BlankLeft g a -> BlankLeft g b) -> g a -> g b
module Blanks.Scope
-- | A simple wrapper for your expression functor that knows how to
-- name-bind. See Blank for usage, and see the patterns in this
-- module for easy manipulation and inspection.
newtype Scope n f a
Scope :: ScopeW Identity n f (Scope n f) a -> Scope n f a
[unScope] :: Scope n f a -> ScopeW Identity n f (Scope n f) a
pattern ScopeBound :: Int -> Scope n f a
pattern ScopeFree :: a -> Scope n f a
pattern ScopeBinder :: Int -> n -> Scope n f a -> Scope n f a
pattern ScopeEmbed :: f (Scope n f a) -> Scope n f a
instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Blanks.Scope.Scope n f)
instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Blanks.Scope.Scope n f)
instance GHC.Base.Functor f => GHC.Base.Functor (Blanks.Scope.Scope n f)
instance GHC.Base.Functor f => Blanks.Interface.Blank (Blanks.Scope.Scope n f)
instance Blanks.NatNewtype.NatNewtype (Blanks.ScopeW.ScopeW Data.Functor.Identity.Identity n f (Blanks.Scope.Scope n f)) (Blanks.Scope.Scope n f)
instance GHC.Base.Functor f => GHC.Base.Applicative (Blanks.Scope.Scope n f)
instance GHC.Base.Functor f => GHC.Base.Monad (Blanks.Scope.Scope n f)
instance (GHC.Classes.Eq (f (Blanks.Scope.Scope n f a)), GHC.Classes.Eq n, GHC.Classes.Eq a) => GHC.Classes.Eq (Blanks.Scope.Scope n f a)
instance (GHC.Show.Show (f (Blanks.Scope.Scope n f a)), GHC.Show.Show n, GHC.Show.Show a) => GHC.Show.Show (Blanks.Scope.Scope n f a)
module Blanks.LocScope
-- | A Scope annotated with some information between constructors.
-- See Blank for usage, and see the patterns in this module for
-- easy manipulation and inspection.
newtype LocScope l n f a
LocScope :: ScopeW (Located l) n f (LocScope l n f) a -> LocScope l n f a
[unLocScope] :: LocScope l n f a -> ScopeW (Located l) n f (LocScope l n f) a
pattern LocScopeBound :: l -> Int -> LocScope l n f a
pattern LocScopeFree :: l -> a -> LocScope l n f a
pattern LocScopeBinder :: l -> Int -> n -> LocScope l n f a -> LocScope l n f a
pattern LocScopeEmbed :: l -> f (LocScope l n f a) -> LocScope l n f a
-- | Extract the location (annotation) from this scope.
locScopeLocation :: LocScope l n f a -> l
-- | Forget all the annotations and yield a plain Scope.
locScopeForget :: Functor f => LocScope l n f a -> Scope n f a
instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Blanks.LocScope.LocScope l n f)
instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Blanks.LocScope.LocScope l n f)
instance GHC.Base.Functor f => GHC.Base.Functor (Blanks.LocScope.LocScope l n f)
instance GHC.Base.Functor f => Blanks.Interface.Blank (Blanks.LocScope.LocScope l n f)
instance Blanks.NatNewtype.NatNewtype (Blanks.ScopeW.ScopeW (Blanks.Located.Located l) n f (Blanks.LocScope.LocScope l n f)) (Blanks.LocScope.LocScope l n f)
instance (GHC.Base.Monoid l, GHC.Base.Functor f) => GHC.Base.Applicative (Blanks.LocScope.LocScope l n f)
instance (GHC.Base.Monoid l, GHC.Base.Functor f) => GHC.Base.Monad (Blanks.LocScope.LocScope l n f)
instance (GHC.Base.Monoid l, GHC.Base.Functor f) => Control.Monad.Writer.Class.MonadWriter l (Blanks.LocScope.LocScope l n f)
instance (GHC.Classes.Eq (f (Blanks.LocScope.LocScope l n f a)), GHC.Classes.Eq l, GHC.Classes.Eq n, GHC.Classes.Eq a) => GHC.Classes.Eq (Blanks.LocScope.LocScope l n f a)
instance (GHC.Show.Show (f (Blanks.LocScope.LocScope l n f a)), GHC.Show.Show l, GHC.Show.Show n, GHC.Show.Show a) => GHC.Show.Show (Blanks.LocScope.LocScope l n f a)
-- | Fill-in-the-blanks - A library factoring out substitution from ASTs.
--
-- It's a pain to track de Bruijn indices yourself to implement
-- capture-avoiding subsititution, so this library provides some wrappers
-- that help. One of the best libraries for this is bound, which
-- uses a clever representation to make these operations safe and fast.
-- The tradeoff is that you have to define a Monad instance for
-- your expression functor, which in practice can be tricky. (It's even
-- trickier to derive Eq and Show!)
--
-- This library takes the simpler, slower, and rather "succ-y"
-- free-monad-ish approach, but with a twist. It expects you to rewrite
-- all name-binding constructors in your expression as annotations on a
-- single "binder" constructor. This allows you to use the provided
-- Scope type (or a variant) as a wrapper around your expression
-- functor, which is only required to implement Functor. This
-- representation is less safe (since you can inspect and manipulate
-- bound variables), but if you stick to the provided combinators, things
-- will work out fine.
--
-- You'll get most of what you want by just importing this module
-- unqualified. See the Blanks class definition and related
-- methods to manipulate variables and abstractions. See Scope for
-- the basic wrapper and LocScope for a wrapper with annotations
-- you can use for source locations and the like. See the test suite for
-- examples.
module Blanks