Skip to content

Releases: lambdageek/unbound-generics

0.4.4

21 Mar 00:42
c44b60a
Compare
Choose a tag to compare

What's changed

  • Add Alpha and Subst instances for NonEmpty. Thanks Brent Yorgey (byorgey)
  • Add GHC 9.8 to CI matrix
  • Bump base >= 4.9
  • Remove tested-with: 7.x in unbound-generics.cabal. We removed CI testing with GHC 7.x last year.
  • Move GSubst from Unbound.Generics.LocallyNameless.Subst into a separate Internal module 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

27 Apr 03:18
bd9bac1
Compare
Choose a tag to compare

What's Changed

  • New function instantiate function that substitutes a list of terms for a collection of bound variables in a toplevel Bind p t term.
    New function substBind operation that substitutes for the bound variable of a Bind (Name a) t term.
    This is a specialization of instantiate to the case where the pattern is a single Name a
  • Expose Rec constructor of the Rec type and the ctxLevel function from AlphaCtx
  • 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

20 May 14:04
Compare
Choose a tag to compare

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

18 Sep 01:52
Compare
Choose a tag to compare

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 which isvar or isCoerceVar 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 as MetaVar "u" [("x", 10)], we may want to
    substitute a Meta ("x" + "x") for "u" to get 10 + 10 (that is, we replace "u" by the expression "x" + "x" and immediately apply the substitution 10 for "x").

    Now suppose we have an expression e2 defined as MetaVar "v" [("y", e1)] (that is, an occurrence of meta var "v" together with a substitution of e1 from above for "y"). If we again try to substitute Meta ("x" + "x") for "u" in e2, we would expect to get MetaVar "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, so e1 becomes 10 + 10 as
    before).

    The bug in previous versions of unbound-generics was that we would incorrectly leave MetaVar "v" [("y", e1)] unchanged as soon as we saw that isCoerceVar (MetaVar "v" [("y", e1)]) returned Just (SubstCoerce "u" ...) where "u" /= "v".

    Thanks Reed Mullanix (TOTWBF) for finding and fixing this issue.
    #26

  • 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 beneath Ignore. 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 on Name a for all a, 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 the Ignore Ty.

    Thanks Reed Mullanix (TOTWBF) for the new operation.

Version 0.3.4

17 Sep 23:55
Compare
Choose a tag to compare

This release is meant to be compatible with GHC-8.6.1 / containers-0.6

Version 0.3.3

11 May 03:07
Compare
Choose a tag to compare

Bump exceptions bound to >= 0.8 && < 0.11 to allow exceptions-0.10.0

Version 0.3.2

09 Mar 05:26
Compare
Choose a tag to compare
  • Bump deepseq >= 1.4.0.0 remove benchmark dependency on deepseq-generics
    when building with GHC >= 7.10
  • Tested with GHC 8.4.1
  • Tested with GHC 8.2.2
  • Compile with -Wcompat
  • Add Semigroup instances for all types that were previously Monoid instances
  • Added more examples to the examples/ directory
  • Added exceptions dependency and MonadThrow, MonadCatch, MonadMask instances for FreshMT and LFreshMT.

Version 0.3.1

24 May 02:06
Compare
Choose a tag to compare

Compiled with GHC 8.0.1

Removed Generic a constraint on Subst b (Name a) instance

v0.2

01 Aug 16:01
Compare
Choose a tag to compare
  • Make Embed an instance of Ord
  • Provide NFData instances for all the combinators.
    Depend on 'deepseq'
  • Re-implement freshen' and gfreshen using a free monad to give
    GHC a chance to inline it all away. This changes the type of
    gfreshen. Major version bump.
    • Expose FFM, liftFFM and retractFFM
  • Start benchmarking some of the operations (particularly unbind).

v0.1.2

08 May 21:12
Compare
Choose a tag to compare
  • Added Shift type for lifting the scope of an Embed combinator up one binding level.
  • (in 0.1.1, which never went to Hackage) Added a makeClosedAlpha TH splice for making 'Alpha' instances for types that don't participate in Alpha in a non-trivial way. A type T is trivial with respect to Alpha if:
    • it cannot contain any names
    • thus its aeq is just (==)
    • and open and close are both identity operations.