- Add
Alpha
andSubst
instances forNonEmpty
. Thanks Brent Yorgey (byorgey) - Add GHC 9.8 to CI matrix
- Bump
base
>= 4.9 - Remove
tested-with: 7.x
inunbound-generics.cabal
. We removed CI testing with GHC 7.x last year. - Move GSubst from
Unbound.Generics.LocallyNameless.Subst
into a separateInternal
module that is exported. Now users can write their own generic traversals. Thanks Bohdan Liesnikov (liesnikov) - Welcome Austin Erlandson (erlandsona) as a maintainer
- Add an
instantiate
function that substitutes a list of terms for a collection of bound variables in a toplevelBind p t
term. Thanks to Stephanie Weirich (sweirich). This adds a newsubstBvs
function to theSubst
class. - Add
substBind
operation that substitutes for the bound variable of aBind (Name a) t
term. This is a specialization ofinstantiate
to the case where the pattern is a singleName a
- Tests for
substBind
by Mark Lemay (marklemay) Thanks! - Expose
Rec
constructor of theRec
type and thectxLevel
function fromAlphaCtx
- Require
transformers < 0.6
, run CI with GHC 9.4, drop CI with GHC 7.10. Thanks to Andreas Abel (andreaasabel).
- Add
Functor
instance forUnbound.Generics.LocallyNameless.Internal.Iso.Exchange
Thanks to Emily Pillmore (emilypi) - Import
MonadPlus
andMonadFix
explicitly when building with mtl-2.3 - Builds with GHC 9.0, GHC 9.2
-
Add
MonadFail
instances forLFreshMT
andFreshMT
-
Builds with GHC 8.10
-
New binding specification type
Ignore
.Any two
Ignore T
terms will always be alpha-equivalent to each other, will be considered to contain no variables, and will not have any substitution apply beneathIgnore
. Useful for attaching annotation terms to your AST.import Text.Parsec.Pos (SourcePos) data Expr = ... | Lambda (Ignore SourcePos) (Bind (Name Expr) Expr)
As expected, any two
Lambda
expressions will be considered alpha-equivalent even if they differ in source position.Note that the
Ignore
will block operations onName a
for alla
, which can be a little unexpected:data Ty = TyVar (Name Ty) | TyArr Ty Ty instance Subst Ty Ty where ... data Expr = ... | Var (Name Expr) | Lambda (Ignore Ty) (Bind (Name Expr) Expr) instance Subst Ty Expr
Applying a substitution of a type for a free type variable to a
Lambda
will not descend into theIgnore Ty
.Thanks Reed Mullanix (TOTWBF) for the new operation.
-
Fix an issue in substitution where traversal would not continue in an AST node for which
isvar
orisCoerceVar
is defined to return non-Nothing
but which had additional structure.For example, in a language with meta variables and explicit substitutions:
data Expr = ... -- normal variables that stand for expressions | Var (Name Expr) -- a meta variable occurrence and an explicit substitution -- of expressions to substitute in for the free variables | MetaVar (Name Meta) [(Name Expr, Expr)] -- a meta variable stands for an expression with some free term vars data Meta = MetaVar Expr -- substitution for a meta in an expression instance Subst Expr Meta where isCoerceVar (MetaVar u sub) = Just (SubstCoerce u (Just . applyExplicitSubst sub)) applyExplicitSubst :: [(Name Expr, Expr)] -> Meta -> Expr applyExplicitSubst s (MetaVar e) = substs s e
Given an expression
e1
defined asMetaVar "u" [("x", 10)]
, we may want to substitute aMeta ("x" + "x")
for"u"
to get10 + 10
(that is, we replace"u"
by the expression"x" + "x"
and immediately apply the substitution10
for"x"
).Now suppose we have an expression
e2
defined asMetaVar "v" [("y", e1)]
(that is, an occurrence of meta var "v" together with a substitution ofe1
from above for"y"
). If we again try to substituteMeta ("x" + "x")
for"u"
ine2
, we would expect to getMetaVar "v" [("y", 10 + 10)]
(that is, since "v" is not equal to "u", we leave the meta var alone, but substitute for any occurrences of "u" in the explicit substitution, soe1
becomes10 + 10
as before).The bug in previous versions of
unbound-generics
was that we would incorrectly leaveMetaVar "v" [("y", e1)]
unchanged as soon as we saw thatisCoerceVar (MetaVar "v" [("y", e1)])
returnedJust (SubstCoerce "u" ...)
where"u" /= "v"
.Thanks Reed Mullanix (TOTWBF) for finding and fixing this issue. #26
- Bump
containers
upper bound to support0.6
. (GHC 8.6.1 support) Thanks Christiaan Baaij.
- Bump
exceptions
upper bound to support0.10.0
- Bump
deepseq >= 1.4.0.0
remove benchmark dependency ondeepseq-generics
- Tested with GHC 8.4.1
- Tested with GHC 8.2.2
- Compile with
-Wcompat
- Add
Semigroup
instances for all types that were previouslyMonoid
instances - Added more examples to the examples/ directory
- Added "exceptions" dependency and
MonadThrow
,MonadCatch
,MonadMask
instances forFreshMT
andLFreshMT
. Thanks Alex McKenna.
- Tested with GHC 8.0.1
- Removed
Generic b
constraint fromSubst b (Name a)
instance.
- Change types of
open
andclose
to takeNthPatFind
andNamePatFind
instead of generic patterns, update call sites. - Add newtype wrappers and Monoid instances for
NthPatFind
andNamePatFind
- Change
isTerm
to returnAll
instead ofBool
-
Incorporating some of the extras/oversights from clash-lib Unbound.Generics.LocallyNameless.Extra
- Make
Embed
an instance ofOrd
NFData
instances (see below)
- Make
-
Re-implement
freshen'
andgfreshen
using a free monad to give GHC a chance to inline it all away. This changes the type ofgfreshen
. Major version bump.- Expose
FFM
,liftFFM
andretractFFM
- Expose
-
Provide
NFData
instances for all the combinators. Depend on 'deepseq' -
Start benchmarking some of the operations (particularly
unbind
).
- Fix ghc-7.10 build.
- Haddock cleanup.
-
Added
IsEmbed
typeclass- Depend on 'profunctors'
-
Changed
embed
andunembed
to work over anyIsEmbed
type. -
Added
Shift
type for shifting the scope of embedded terms out one level.
- Added
isNullDisjointSet
function. - Implement a TH
makeClosedAlpha
splice for constructing trivial leaf instances.
-
Add
acompare
functiona andacompare'
method toAlpha
typeclass. (christiaanb)Handwritten
Alpha
instances will need to define this additional method now. Major version bump.
-
Add 'name2Integer' method (christiaanb)
-
Export internal type-directed
gaeq
,gopen
,gclose
, etc functions fromUnbound.Generics.LocallyNameless.Alpha
.Allows definitions like:
instance Alpha Term where aeq' _ (Prim t1 _dk1) (Prim t2 _dk2) = t1 == t2 aeq' c t1 t2 = gaeq c (from t1) (from t2)
- Unconditionally add ErrorT and ExceptT instances using transformers-compat (bergmark)
-
Add 'Rec' pattern and 'TRec' term combinators.
-
Alpha instance for '()'
-
Add 'lunbind2' function.
-
Doc updates.
-
Switch from 'HUnit' to 'Tasty' for testing.
- Initial (re-)implementation effort.