Releases: lambdageek/unbound-generics
0.4.4
What's changed
- Add
AlphaandSubstinstances forNonEmpty. Thanks Brent Yorgey (byorgey) - Add GHC 9.8 to CI matrix
- Bump
base>= 4.9 - Remove
tested-with: 7.xinunbound-generics.cabal. We removed CI testing with GHC 7.x last year. - Move GSubst from
Unbound.Generics.LocallyNameless.Substinto a separateInternalmodule that is exported. Now users can write their own generic traversals.
Thanks Bohdan Liesnikov (liesnikov) - Welcome Austin Erlandson (erlandsona) as a maintainer
Full Changelog: v0.4.3...v0.4.4
Version 0.4.3
What's Changed
- New function
instantiatefunction that substitutes a list of terms for a collection of bound variables in a toplevelBind p tterm.
New functionsubstBindoperation that substitutes for the bound variable of aBind (Name a) tterm.
This is a specialization ofinstantiateto the case where the pattern is a singleName a - Expose
Recconstructor of theRectype and thectxLevelfunction fromAlphaCtx - Drop CI testing with GHC 7.10, add CI testing with GHC 9.4
- Fix compilation with
transformers >= 0.6
Full Changelog: v0.4.2...v0.4.3
Version 0.4.2
What's Changed
- This is a maintenance release that adds support for building with GHC 9.2
Full Changelog: v0.4.0...v0.4.2
Version 0.4.0
This release brings a bug fix that may be a breaking change for some ASTs, and a new combinator.
-
Fix an issue in substitution where traversal would not continue in
an AST node for whichisvarorisCoerceVaris defined to return
non-Nothingbut 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
e1defined 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 substitution10for"x").Now suppose we have an expression
e2defined asMetaVar "v" [("y", e1)](that is, an occurrence of meta var "v" together with a substitution ofe1from 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, soe1becomes10 + 10as
before).The bug in previous versions of
unbound-genericswas 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 -
New binding specification type
Ignore.Any two
Ignore Tterms 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
Lambdaexpressions will be considered alpha-equivalent even if they differ in source position.Note that the
Ignorewill block operations onName afor 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
Lambdawill not descend into theIgnore Ty.Thanks Reed Mullanix (TOTWBF) for the new operation.
Version 0.3.4
This release is meant to be compatible with GHC-8.6.1 / containers-0.6
Version 0.3.3
Bump exceptions bound to >= 0.8 && < 0.11 to allow exceptions-0.10.0
Version 0.3.2
- Bump
deepseq >= 1.4.0.0remove benchmark dependency ondeepseq-generics
when building with GHC >= 7.10 - Tested with GHC 8.4.1
- Tested with GHC 8.2.2
- Compile with
-Wcompat - Add
Semigroupinstances for all types that were previouslyMonoidinstances - Added more examples to the examples/ directory
- Added
exceptionsdependency andMonadThrow,MonadCatch,MonadMaskinstances forFreshMTandLFreshMT.
Version 0.3.1
Compiled with GHC 8.0.1
Removed Generic a constraint on Subst b (Name a) instance
v0.2
- Make
Embedan instance ofOrd - Provide
NFDatainstances for all the combinators.
Depend on 'deepseq' - Re-implement
freshen'andgfreshenusing a free monad to give
GHC a chance to inline it all away. This changes the type of
gfreshen. Major version bump.- Expose
FFM,liftFFMandretractFFM
- Expose
- Start benchmarking some of the operations (particularly
unbind).
v0.1.2
- Added
Shifttype for lifting the scope of anEmbedcombinator up one binding level. - (in 0.1.1, which never went to Hackage) Added a
makeClosedAlphaTH splice for making 'Alpha' instances for types that don't participate inAlphain a non-trivial way. A typeTis trivial with respect toAlphaif:- it cannot contain any names
- thus its
aeqis just(==) - and
openandcloseare both identity operations.