exception DoesntCheck
fun datatype_by_constructor(datatypes, constructor_name) =
case
(List.find
(fn
(cons, dname, t
) => cons
=constructor_name
) datatypes
) of NONE => NONE
| SOME (c,d,t) => SOME d
fun get_pattern_type ds p =
let fun get_tuple_type(t) =
map (fn p => get_pattern_type ds p) t
in
case p of
UnitP => UnitT
| ConstP _ => IntT
| Wildcard => Anything
| Variable name => Anything
| TupleP ps => TupleT (get_tuple_type(ps))
| ConstructorP(name,v) => case datatype_by_constructor(ds, name) of SOME name => Datatype name | NONE => raise DoesntCheck
end
fun get_common_type(t1, t2) =
let fun get_common_tuple_type(ts1, ts2) =
map (fn (t1,t2) => get_common_type(t1,t2)) (ListPair.zip(ts1, ts2))
in
case (t1, t2) of
(UnitT, UnitT) => UnitT
| (IntT, IntT) => IntT
| (Anything, x) => x
| (x, Anything) => x
| (Datatype name1, Datatype name2) => if name1=name2 then Datatype name1 else raise DoesntCheck
| (TupleT ts1, TupleT ts2) => TupleT(get_common_tuple_type(ts1, ts2))
| _ => raise DoesntCheck
end
fun typecheck_patterns (datatypes, patterns) =
let
val ptype = get_pattern_type datatypes
fun find_common_type(head, tail) =
foldl (fn (p, acc) => get_common_type(ptype(p), acc)) (ptype(head)) tail
in
case patterns of
[] => NONE
| h::t => (SOME (find_common_type(h, t))) handle DoesntCheck => NONE
end
ZXhjZXB0aW9uIERvZXNudENoZWNrCgpmdW4gZGF0YXR5cGVfYnlfY29uc3RydWN0b3IoZGF0YXR5cGVzLCBjb25zdHJ1Y3Rvcl9uYW1lKSA9CgljYXNlIChMaXN0LmZpbmQgKGZuIChjb25zLCBkbmFtZSwgdCkgPT4gY29ucz1jb25zdHJ1Y3Rvcl9uYW1lKSBkYXRhdHlwZXMpIG9mCgkJTk9ORSA9PiBOT05FCgkJfCBTT01FIChjLGQsdCkgPT4gU09NRSBkCgoKZnVuIGdldF9wYXR0ZXJuX3R5cGUgZHMgcCA9CglsZXQgZnVuIGdldF90dXBsZV90eXBlKHQpID0KCQltYXAgKGZuIHAgPT4gZ2V0X3BhdHRlcm5fdHlwZSBkcyBwKSB0CglpbgoJCWNhc2UgcCBvZiAKCQkJVW5pdFAgPT4gVW5pdFQKCQkJfCBDb25zdFAgXyA9PiBJbnRUCgkJCXwgV2lsZGNhcmQgPT4gQW55dGhpbmcKCQkJfCBWYXJpYWJsZSBuYW1lID0+IEFueXRoaW5nCgkJCXwgVHVwbGVQIHBzID0+IFR1cGxlVCAoZ2V0X3R1cGxlX3R5cGUocHMpKQoJCQl8IENvbnN0cnVjdG9yUChuYW1lLHYpID0+IGNhc2UgZGF0YXR5cGVfYnlfY29uc3RydWN0b3IoZHMsIG5hbWUpIG9mIFNPTUUgbmFtZSA9PiBEYXRhdHlwZSBuYW1lIHwgTk9ORSA9PiByYWlzZSBEb2VzbnRDaGVjawoJZW5kCgpmdW4gZ2V0X2NvbW1vbl90eXBlKHQxLCB0MikgPSAKCglsZXQgZnVuIGdldF9jb21tb25fdHVwbGVfdHlwZSh0czEsIHRzMikgPSAKCQltYXAgKGZuICh0MSx0MikgPT4gZ2V0X2NvbW1vbl90eXBlKHQxLHQyKSkgKExpc3RQYWlyLnppcCh0czEsIHRzMikpCglpbgoJCWNhc2UgKHQxLCB0Mikgb2YKCQkJKFVuaXRULCBVbml0VCkgPT4gVW5pdFQKCQkJfCAoSW50VCwgSW50VCkgPT4gSW50VAoJCQl8IChBbnl0aGluZywgeCkgPT4geAoJCQl8ICh4LCBBbnl0aGluZykgPT4geAoJCQl8IChEYXRhdHlwZSBuYW1lMSwgRGF0YXR5cGUgbmFtZTIpID0+IGlmIG5hbWUxPW5hbWUyIHRoZW4gRGF0YXR5cGUgbmFtZTEgZWxzZSByYWlzZSBEb2VzbnRDaGVjawoJCQl8IChUdXBsZVQgdHMxLCBUdXBsZVQgdHMyKSA9PiBUdXBsZVQoZ2V0X2NvbW1vbl90dXBsZV90eXBlKHRzMSwgdHMyKSkKCQkJfCBfID0+IHJhaXNlIERvZXNudENoZWNrCgllbmQKCmZ1biB0eXBlY2hlY2tfcGF0dGVybnMgKGRhdGF0eXBlcywgcGF0dGVybnMpID0KCWxldCAKCQl2YWwgcHR5cGUgPSBnZXRfcGF0dGVybl90eXBlIGRhdGF0eXBlcwoJCWZ1biBmaW5kX2NvbW1vbl90eXBlKGhlYWQsIHRhaWwpID0gCgkJCWZvbGRsIChmbiAocCwgYWNjKSA9PiBnZXRfY29tbW9uX3R5cGUocHR5cGUocCksIGFjYykpIChwdHlwZShoZWFkKSkgdGFpbAoJaW4KCQljYXNlIHBhdHRlcm5zIG9mCgkJCVtdID0+IE5PTkUKCQkJfCBoOjp0ID0+IChTT01FIChmaW5kX2NvbW1vbl90eXBlKGgsIHQpKSkgaGFuZGxlIERvZXNudENoZWNrID0+IE5PTkUKCWVuZAo=