TAD de tipo¶
(define-datatype type type?
(atomic-type (name symbol?))
(proc-type
(arg-types (list-of type?))
(result-type type?))
(tvar-type
(serial-number integer?)
(container vector?)))
Agregamos el caso cuando es ? (variable de tipo)
Check-equal-type¶
(define check-equal-type!
...
((tvar-type? t1) (check-tvar-equal-type! t1 t2 exp))
((tvar-type? t2) (check-tvar-equal-type! t2 t1 exp))
...
Cuando son variables de tipo entonces cambia el comportamiento
(define check-tvar-equal-type!
(lambda (tvar ty exp)
(if (tvar-non-empty? tvar)
(check-equal-type! (tvar->contents tvar) ty exp)
(begin
(check-no-occurrence! tvar ty exp)
(tvar-set-contents! tvar ty)))))
- Si no esta vacia, compara los tipos
- Si esta vacia, asigna uno validando que no existan recursiones.
- check-no-occurrence! valida que si es tipo procval, no exista la misma variable de tipo dentro del procedimiento: utilidad lo del numero serial
Ejemplos¶
(type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in f")))
(tvar3 -> tvar3)
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in f")))
(tvar4 -> tvar4)
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in (f 5)")))
int
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f 5) in f")))
(int -> int)
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f true) in f")))
(bool -> bool)
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f proc(int y) +(y,3)) in f")))
((int -> int) -> (int -> int))
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f proc(? y) +(y,3)) in f")))
((int -> int) -> (int -> int))
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f proc(? y) y) in f")))
((tvar19 -> tvar19) -> (tvar19 -> tvar19))
(type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f proc(? x, ? y) +(x,3) ) in f")))
((int * tvar3 -> int) -> (int * tvar3 -> int))
> (type-to-external-form (type-of-program (scan&parse "let f = proc(? x) x
in let k = (f proc(? x, ? y) (y +(x,3)) ) in f")))
((int * (int -> tvar10) -> tvar10) -> (int * (int -> tvar10) -> tvar10))
En los casos que encontramos tvar es que no se puede determinar el tipo con lo que tenemos, a esto se le conoce como tipo polimorfico