An implementation of Algorithm W (and an interpreter) for a simple lambda-calculus.
You have installed Leiningen and Git
Clone the repository:
git clone https://github.com/ericnormand/hindley-milner
cd hindley-milner
lein repl
user>
user> (ns user
(:refer-clojure :exclude [eval])
(:require [hindley-milner.syntax :refer :all]
[hindley-milner.eval :refer :all]
[hindley-milner.types :refer :all]))
user> '(fn [a] x)
(fn [a] x)
user> (lambda? '(fn [a] x))
true
user> (free-vars '(let [a x
b y]
(((z a) b) c)))
#{'x 'y 'z 'c}
user> (interpret env 1)
1
user> (interpret env
'(let [c (dec b)
id (fn a a)
b 2]
(id c)))
1
user> (infer tenv 1)
:Integer
user> (infer* tenv '(if true 1 2))
[:Lambda :Integer]
user> (let [[_ [_] [_ [_ _ x] y]]
(infer* tenv '(fn [a]
(let [x (fn [b]
(let [y (fn [c]
(a 1))]
(y 2)))]
(x 3))))]
(= x y))
true
To run the tests:
lein test
Pull requests welcome!
- Implement Hindley-Milner in Clojure (DONE!)
- Learn and teach about type systems
- Discover similarities between Lisp's meta-circular
eval
and syntax-directed HM.
- To type check Clojure.
- Add support for inferencing multiple bindings in a
let
. - Add negative tests
- Docstrings
Copyright © 2014 Eric Normand
Please see http://lispcast.com/Hindley-Milner-in-Clojure for rationale.
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.