Crate moniker

source ·
Expand description

Automatically derive variable binding and alpha equivalence for abstract syntax trees.

Example

Here is an example of how you might use moniker to define the AST for the simply typed lambda calculus:

#[macro_use]
extern crate moniker;

use std::rc::Rc;
use moniker::{Embed, Nest, Binder, Scope, Var};

#[derive(Debug, Clone, BoundTerm)]
pub enum Type {
    Base,
    Arrow(Rc<Type>, Rc<Type>),
}

#[derive(Debug, Clone, BoundTerm)]
pub enum Expr {
    Var(Var<String>),
    Lam(Scope<(Binder<String>, Embed<Rc<Type>>), Rc<Expr>>),
    Let(Scope<Nest<(Binder<String>, Embed<(Rc<Type>, Rc<Expr>)>)>, Rc<Expr>>),
    App(Rc<Expr>, Rc<Expr>),
}

Overview of traits and data types

We separate data types into terms and patterns:

Terms

Terms are data types that implement the BoundTerm trait.

Implementations for tuples, strings, numbers, slices, vectors, and mart pointers are also provided for convenience.

Patterns

Patterns are data types that implement the BoundPattern trait.

Implementations for tuples, strings, numbers, slices, vectors, and mart pointers are also provided for convenience.

Macros

Assert that two expressions are alpha equivalent to each other (using BoundPattern::pattern_eq).
Assert that two expressions are alpha equivalent to each other (using BoundTerm::term_eq).

Structs

Embed a term in a pattern
A free variable
Data that does not participate in name binding
Nested binding patterns
Recursively bind a pattern in itself
A bound scope
The Debruijn index of the binder that introduced the variable
A generated id

Enums

A variable that can either be free or bound

Traits

Patterns that bind variables in terms
Terms that may contain variables that can be bound by patterns