https://github.com/jakobknauer/hindley-milner
An implementation of Algorithm J for type inference in the Hindley-Milner type system, written in Rust
https://github.com/jakobknauer/hindley-milner
algorithm-j hindley-milner type-inference
Last synced: 10 months ago
JSON representation
An implementation of Algorithm J for type inference in the Hindley-Milner type system, written in Rust
- Host: GitHub
- URL: https://github.com/jakobknauer/hindley-milner
- Owner: jakobknauer
- License: mit
- Created: 2025-06-12T18:56:55.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-06-14T16:21:44.000Z (12 months ago)
- Last Synced: 2025-06-14T16:45:04.543Z (12 months ago)
- Topics: algorithm-j, hindley-milner, type-inference
- Language: Rust
- Homepage:
- Size: 19.5 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
A Rust implementation of [Algorithm J](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system#Algorithm_J) for type inference in the [Hindley-Milner type system](https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system).
Furthermore, the repo includes:
- a parser for expressions and types,
- an equality check for types that respects renaming of bound variables,
- unit tests for the parser and the inference algorithm, and
- a REPL for inferring types of user-provided expressions (on empty context; for examples with non-empty context, see the unit tests in [src/algorithm_j.rs](src/algorithm_j.rs)).
Run the program to try out the REPL:
```
cargo run
...
>>> lambda x . x
⊢ λx . x : ∀ _1 . _1 → _1
>>> lambda f . lambda x . f x
⊢ λf . λx . f x : ∀ _3 _2 . (_2 → _3) → _2 → _3
>>> lambda f . lambda x . f (f x)
⊢ λf . λx . f (f x) : ∀ _4 . (_4 → _4) → _4 → _4
```
Caveats:
- The parser accepts the ASCII alternatives `lambda` for `λ`, `forall` for `∀`, and `to` for `→`.
- The parser only accepts alphanumeric identifiers starting with a letter.
- When parsing types, the parser interprets identifiers starting with a small letter as type variables, and identifiers starting with a capital letter as type constructors.
- As seen in the example above, fresh variables generated during inference are of the form `_1`, `_2`, etc., and thus cannot collide with parsed variables.
- The notation (identifiers in the code etc.) as well as the algorithm itself closely follow the description on Wikipedia.