```-----------------------------------------------------------------------------
-- |
-- Module      :  Bound
-- Copyright   :  (C) 2012 Edward Kmett
-- License     :  BSD-style (see the file LICENSE)
--
-- Maintainer  :  Edward Kmett <ekmett@gmail.com>
-- Stability   :  experimental
-- Portability :  portable
--
-- We represent the target language itself as an ideal monad supplied by the
-- user, and provide a 'Scope' monad transformer for introducing bound
-- variables in user supplied terms. Users supply a 'Monad' and 'Traversable'
-- instance, and we traverse to find free variables, and use the 'Monad' to
-- perform substitution that avoids bound variables.
--
-- An untyped lambda calculus:
--
-- > import Bound
-- > import Prelude.Extras
--
-- > infixl 9 :@
-- > data Exp a = V a | Exp a :@ Exp a | Lam (Scope () Exp a)
-- >  deriving (Eq,Ord,Show,Read,Functor,Foldable,Traversable)
--
-- > instance Eq1 Exp   where (==#)      = (==)
-- > instance Ord1 Exp  where compare1   = compare
-- > instance Show1 Exp where showsPrec1 = showsPrec
-- > instance Applicative Exp where pure = V; (<*>) = ap
--
-- > instance Monad Exp where
-- >   return = V
-- >   V a      >>= f = f a
-- >   (x :@ y) >>= f = (x >>= f) :@ (y >>= f)
-- >   Lam e    >>= f = Lam (e >>>= f)
-- >
-- > lam :: Eq a => a -> Exp a -> Exp a
-- > lam v b = Lam (abstract1 v b)
--
-- > whnf :: Exp a -> Exp a
-- > whnf (f :@ a) = case whnf f of
-- >   Lam b -> whnf (instantiate1 a b)
-- >   f'    -> f' :@ a
-- > whnf e = e
--
----------------------------------------------------------------------------
module Bound
(
-- * Scopes introduce bound variables in user terms
Scope(..)
-- ** Abstraction over bound variables
, abstract, abstract1
-- ** Instantiation of bound variables
, instantiate, instantiate1
-- * Combinators for manipulating user terms
, substitute
, isClosed
, closed
-- * Structures permitting substitution
, Bound(..)
, (=<<<)
-- ** Conversion to Traditional de Bruijn
, Var(..)
, fromScope
, toScope
-- ** Advanced substitution combinators
, splat
, mapBound, mapScope
, liftMBound, liftMScope
, foldMapBound, foldMapScope
, traverseBound_, traverseScope_
, mapMBound_, mapMScope_
, traverseBound, traverseScope
, mapMBound, mapMScope
) where

import Bound.Var
import Bound.Class
import Bound.Scope
import Bound.Term
```