type Int = "Int"; type Bool = "Bool"; type Atom = Int | Bool; type SimpleType = Arrow | Atom; type Arrow = { left: SimpleType; right: SimpleType; }; type Identifier = string; type Binding = { name: Identifier; type?: SimpleType; }; type Abstraction = { binding: Binding; body: ASTNode; }; type ASTNode = Abstraction | Application | Identifier; // class Environment { constructor(private readonly _captures: Map, private readonly _parent?: Environment) {} public add(identifier: Identifier, substitution: T): Environment { const captures = new HashMap(); captures.put(identifier, substitution); return new Environment<>(captures, this); } public get(identifier: Identifier): T? { if (this._captures.has(identifier)) return this._captures.get(identifier); return this._parent?.get(identifier); } } //const tokenize // const parse // const check