unbound-0.2.1: Generic support for programming with names and binders

PortabilityGHC only
MaintainerBrent Yorgey <byorgey@cis.upenn.edu>




Special type combinators for specifying binding structure.



data Bind p t Source

The most fundamental combinator for expressing binding structure is Bind. The term type Bind p t represents a pattern p paired with a term t, where names in p are bound within t.

Like Name, Bind is also abstract. You can create bindings using bind and take them apart with unbind and friends.


B p t 


(Rep p[a1eLk], Rep t[a1eLl], Sat (ctx[a1ePZ] p[a1eLk]), Sat (ctx[a1ePZ] t[a1eLl])) => Rep1 ctx[a1ePZ] (Bind p[a1eLk] t[a1eLl]) 
(Subst c b, Subst c a, Alpha a, Alpha b) => Subst c (Bind a b) 
(Alpha a, Alpha b, Read a, Read b) => Read (Bind a b) 
(Show a, Show b) => Show (Bind a b) 
(Rep p[a1eLk], Rep t[a1eLl]) => Rep (Bind p[a1eLk] t[a1eLl]) 
(Alpha p, Alpha t) => Alpha (Bind p t) 

data Rebind p1 p2 Source

Rebind allows for nested bindings. If p1 and p2 are pattern types, then Rebind p1 p2 is also a pattern type, similar to the pattern type (p1,p2) except that p1 scopes over p2. That is, names within terms embedded in p2 may refer to binders in p1.


R p1 p2 


(Rep p1[a1eLi], Rep p2[a1eLj], Sat (ctx[a1ePE] p1[a1eLi]), Sat (ctx[a1ePE] p2[a1eLj])) => Rep1 ctx[a1ePE] (Rebind p1[a1eLi] p2[a1eLj]) 
(Subst c b, Subst c a, Alpha a, Alpha b) => Subst c (Rebind a b) 
(Alpha p1, Alpha p2, Eq p2) => Eq (Rebind p1 p2)

Compare for alpha-equality.

(Show a, Show b) => Show (Rebind a b) 
(Rep p1[a1eLi], Rep p2[a1eLj]) => Rep (Rebind p1[a1eLi] p2[a1eLj]) 
(Alpha p, Alpha q) => Alpha (Rebind p q) 

data Rec p Source

If p is a pattern type, then Rec p is also a pattern type, which is recursive in the sense that p may bind names in terms embedded within itself. Useful for encoding e.g. lectrec and Agda's dot notation.


Rec p 


(Rep p[a1eLh], Sat (ctx[a1ePw] p[a1eLh])) => Rep1 ctx[a1ePw] (Rec p[a1eLh]) 
(Alpha a, Subst c a) => Subst c (Rec a) 
Show a => Show (Rec a) 
Rep p[a1eLh] => Rep (Rec p[a1eLh]) 
Alpha p => Alpha (Rec p) 

newtype TRec p Source

TRec is a standalone variant of Rec: the only difference is that whereas Rec p is a pattern type, TRec p is a term type. It is isomorphic to Bind (Rec p) ().

Note that TRec corresponds to Pottier's abstraction construct from alpha-Caml. In this context, Embed t corresponds to alpha-Caml's inner t, and Shift (Embed t) corresponds to alpha-Caml's outer t.


TRec (Bind (Rec p) ()) 


Show a => Show (TRec a) 

newtype Embed t Source

Embed allows for terms to be embedded within patterns. Such embedded terms do not bind names along with the rest of the pattern. For examples, see the tutorial or examples directories.

If t is a term type, then Embed t is a pattern type.

Embed is not abstract since it involves no binding, and hence it is safe to manipulate directly. To create and destruct Embed terms, you may use the Embed constructor directly. (You may also use the functions embed and unembed, which additionally can construct or destruct any number of enclosing Shifts at the same time.)


Embed t 


(Rep t[a1eLf], Sat (ctx[a1ePR] t[a1eLf])) => Rep1 ctx[a1ePR] (Embed t[a1eLf]) 
Subst c a => Subst c (Embed a) 
Eq t => Eq (Embed t) 
Show a => Show (Embed a) 
Rep t[a1eLf] => Rep (Embed t[a1eLf]) 
IsEmbed (Embed t) 
Alpha t => Alpha (Embed t) 

newtype Shift p Source

Shift the scope of an embedded term one level outwards.


Shift p 


(Rep p[a1eLe], Sat (ctx[a1ePo] p[a1eLe])) => Rep1 ctx[a1ePo] (Shift p[a1eLe]) 
Eq p => Eq (Shift p) 
Show a => Show (Shift a) 
Rep p[a1eLe] => Rep (Shift p[a1eLe]) 
IsEmbed e => IsEmbed (Shift e) 
Alpha a => Alpha (Shift a) 

Pay no attention to the man behind the curtain

These type representation objects are exported so they can be referenced by auto-generated code. Please pretend they do not exist.

rBind :: forall p[a1eLk] t[a1eLl]. (Rep p[a1eLk], Rep t[a1eLl]) => R (Bind p[a1eLk] t[a1eLl])Source

rRebind :: forall p1[a1eLi] p2[a1eLj]. (Rep p1[a1eLi], Rep p2[a1eLj]) => R (Rebind p1[a1eLi] p2[a1eLj])Source

rEmbed :: forall t[a1eLf]. Rep t[a1eLf] => R (Embed t[a1eLf])Source

rRec :: forall p[a1eLh]. Rep p[a1eLh] => R (Rec p[a1eLh])Source

rShift :: forall p[a1eLe]. Rep p[a1eLe] => R (Shift p[a1eLe])Source