https://github.com/zdimension/hm-infer-scheme
Hindley-Milner type inference in Scheme, for Scheme
https://github.com/zdimension/hm-infer-scheme
hindley-milner racket scheme type-inference
Last synced: about 2 months ago
JSON representation
Hindley-Milner type inference in Scheme, for Scheme
- Host: GitHub
- URL: https://github.com/zdimension/hm-infer-scheme
- Owner: zdimension
- License: mit
- Created: 2022-03-18T09:26:26.000Z (about 4 years ago)
- Default Branch: master
- Last Pushed: 2022-04-15T13:31:22.000Z (about 4 years ago)
- Last Synced: 2025-05-28T22:07:10.306Z (11 months ago)
- Topics: hindley-milner, racket, scheme, type-inference
- Language: Racket
- Homepage:
- Size: 11.7 KB
- Stars: 9
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Hindley-Milner type inference in Scheme, for Scheme
[C# port here](https://github.com/zdimension/hm-infer-cs), [Rust port here](https://github.com/zdimension/hm-infer-rs).
This is a type inference engine built on the Hindley-Milner algorithm, that analyzes, type-checks and computes the type of expressions written in an extended subset of Scheme.
## Supported Scheme constructs
- `(let ([name val] ...) body)`: basic `let`
- `(let* ([name val] ...) body)`: ordered `let` (each symbol can access the symbols defined before it)
- `(letrec ([name val] ...) body)`: `let` with recursion support (symbols can access themselves inside a lambda definition)
- `(lambda (a b ...) body)`: lambda definition
- `(f a b ...)`: procedure application (**difference from Scheme**: implicit partial application; such that `(pair a b)` is strictly equivalent to `((pair a) b)`)
## Built-ins
Types:
- `int` (Scheme `number?`)
- `bool` (Scheme `boolean?`)
- `str` (Scheme `string?`)
- `unit` (void/unit type)
- `bottom` (Haskell `forall a. a`, Rust `!`)
Symbols:
NameSignature (n-ary syntax)
Numbers+, -, *, /, modulo, succ, pred[int int] -> int
=[int int] -> bool
zeroint -> bool
Booleansand, or[bool bool] -> bool
Utilitieserrorstr -> never
if[bool a a] -> a
Pairspair[a b] -> (a * b)
car(a * b) -> a
cdr(a * b) -> b
Listsnil(list a)
cons[a (list a)] -> (list a)
hd(list a) -> a
tl(list a) -> (list a)
null?(list a) -> bool
Eitherlefta -> (either a b)
rightb -> (either a b)
either[(either a b) (a -> x) (b -> y)] -> (either x y)
Maybejusta -> (option a)
nothing(option a)
maybe[(option a) (a -> x)] -> (option x)
## Internals
All functions are internally curried, as in Haskell, e.g. the type of `pair` is `(a -> (b -> (a * b)))`.
This allows for built-in support for partial application (cf. above) in the HM framework, while still allowing to define n-ary functions.
In effect, `(lambda (a b) body)` is syntactic sugar for `(lambda (a) (lambda (b) body))`.