diff --git a/collects/typed-scheme/private/infer.ss b/collects/typed-scheme/private/infer.ss index c4ac9a440a..2694583ebc 100644 --- a/collects/typed-scheme/private/infer.ss +++ b/collects/typed-scheme/private/infer.ss @@ -5,7 +5,7 @@ (require "unify.ss" "type-comparison.ss" "type-rep.ss" "effect-rep.ss" "subtype.ss" "planet-requires.ss" "tc-utils.ss" "union.ss" - "resolve-type.ss" + "resolve-type.ss" "type-utils.ss" "type-effect-convenience.ss" (lib "trace.ss") (lib "plt-match.ss") diff --git a/collects/typed-scheme/private/resolve-type.ss b/collects/typed-scheme/private/resolve-type.ss index 28385b8097..d68de69267 100644 --- a/collects/typed-scheme/private/resolve-type.ss +++ b/collects/typed-scheme/private/resolve-type.ss @@ -1,7 +1,7 @@ #lang scheme/base (require "type-rep.ss" "type-name-env.ss" "tc-utils.ss" - "type-utils.ss" + "type-utils.ss" mzlib/plt-match mzlib/trace) diff --git a/collects/typed-scheme/private/type-rep.ss b/collects/typed-scheme/private/type-rep.ss index 7e88413b72..dd2cdabd4c 100644 --- a/collects/typed-scheme/private/type-rep.ss +++ b/collects/typed-scheme/private/type-rep.ss @@ -1,215 +1,215 @@ #lang scheme/base - - (require "planet-requires.ss" "rep-utils.ss" "effect-rep.ss" "tc-utils.ss" - "free-variance.ss" - mzlib/trace scheme/match - (for-syntax scheme/base)) - - (define name-table (make-weak-hasheq)) - - ;; Name = Symbol - - ;; Type is defined in rep-utils.ss - - ;; t must be a Type - (dt Scope (t)) - - ;; i is an nat - (dt B (i) - [#:frees empty-hash-table (make-immutable-hasheq (list (cons i Covariant)))] - [#:fold-rhs #:base]) - - ;; n is a Name - (dt F (n) [#:frees (make-immutable-hasheq (list (cons n Covariant))) empty-hash-table] [#:fold-rhs #:base]) + +(require "planet-requires.ss" "rep-utils.ss" "effect-rep.ss" "tc-utils.ss" + "free-variance.ss" + mzlib/trace scheme/match + (for-syntax scheme/base)) + +(define name-table (make-weak-hasheq)) + +;; Name = Symbol + +;; Type is defined in rep-utils.ss + +;; t must be a Type +(dt Scope (t)) + +;; i is an nat +(dt B (i) + [#:frees empty-hash-table (make-immutable-hasheq (list (cons i Covariant)))] + [#:fold-rhs #:base]) + +;; n is a Name +(dt F (n) [#:frees (make-immutable-hasheq (list (cons n Covariant))) empty-hash-table] [#:fold-rhs #:base]) + +;; id is an Identifier +(dt Name (id) [#:intern (hash-id id)] [#:frees #f] [#:fold-rhs #:base]) + +;; rator is a type +;; rands is a list of types +;; stx is the syntax of the pair of parens +(dt App (rator rands stx) + [#:intern (list rator rands)] + [#:frees (combine-frees (map free-vars* (cons rator rands))) + (combine-frees (map free-idxs* (cons rator rands)))] + [#:fold-rhs (*App (type-rec-id rator) + (map type-rec-id rands) + stx)]) + +;; left and right are Types +(dt Pair (left right)) + +;; elem is a Type +(dt Vector (elem) [#:frees (make-invariant (free-vars* elem)) (make-invariant (free-idxs* elem))]) + +;; elem is a Type +(dt Box (elem) [#:frees (make-invariant (free-vars* elem)) (make-invariant (free-idxs* elem))]) + +;; name is a Symbol (not a Name) +(dt Base (name) [#:frees #f] [#:fold-rhs #:base]) + +;; body is a Scope +(dt Mu (body) #:no-provide [#:frees (free-vars* body) (without-below 1 (free-idxs* body))] + [#:fold-rhs (*Mu (*Scope (type-rec-id (Scope-t body))))]) + +;; n is how many variables are bound here +;; body is a Scope +(dt Poly (n body) #:no-provide + [#:frees (free-vars* body) (without-below n (free-idxs* body))] + [#:fold-rhs (let ([body* (remove-scopes n body)]) + (*Poly n (add-scopes n (type-rec-id body*))))]) + +;; n is how many variables are bound here +;; there are n-1 'normal' vars and 1 ... var +;; body is a Scope +(dt PolyDots (n body) #:no-provide + [#:frees (free-vars* body) (without-below n (free-idxs* body))] + [#:fold-rhs (let ([body* (remove-scopes n body)]) + (*PolyDots n (add-scopes n (type-rec-id body*))))]) + +;; pred : identifier +;; cert : syntax certifier +(dt Opaque (pred cert) [#:intern (hash-id pred)] [#:frees #f] [#:fold-rhs #:base]) + +;; name : symbol +;; parent : Struct +;; flds : Listof[Type] +;; proc : Function Type +;; poly? : is this a polymorphic type? +;; pred-id : identifier for the predicate of the struct +;; cert : syntax certifier for pred-id +(dt Struct (name parent flds proc poly? pred-id cert) + [#:intern (list name parent flds proc)] + [#:frees (combine-frees (map free-vars* (append (if proc (list proc) null) (if parent (list parent) null) flds))) + (combine-frees (map free-idxs* (append (if proc (list proc) null) (if parent (list parent) null) flds)))] + [#:fold-rhs (*Struct name + (and parent (type-rec-id parent)) + (map type-rec-id flds) + (and proc (type-rec-id proc)) + poly? + pred-id + cert)]) + +;; dom : Listof[Type] +;; rng : Type +;; rest : Option[Type] +;; drest : Option[Cons[Type,Name or nat]] +;; rest and drest NOT both true +;; thn-eff : Effect +;; els-eff : Effect +;; arr is NOT a Type +(dt arr (dom rng rest drest thn-eff els-eff) + [#:frees (combine-frees (append (map flip-variances (map free-vars* (append (if rest (list rest) null) dom))) + (match drest + [(cons t (? symbol? bnd)) + (let ([vs (free-vars* t)]) + (flip-variances (fix-bound vs bnd)))] + [(cons t bnd) (flip-variances (free-vars* t))] + [_ null]) + (list (free-vars* rng)) + (map make-invariant + (map free-vars* (append thn-eff els-eff))))) + (combine-frees (append (map flip-variances (map free-idxs* (append (if rest (list rest) null) dom))) + (match drest + [(cons t (? number? bnd)) + (let ([vs (free-idxs* t)]) + (flip-variances (fix-bound vs bnd)))] + [(cons t bnd) (flip-variances (free-idxs* t))] + [_ null]) + (list (free-idxs* rng)) + (map make-invariant + (map free-idxs* (append thn-eff els-eff)))))] + [#:fold-rhs (*arr (map type-rec-id dom) + (type-rec-id rng) + (and rest (type-rec-id rest)) + (and drest (cons (type-rec-id (car drest)) (cdr drest))) + (map effect-rec-id thn-eff) + (map effect-rec-id els-eff))]) + +;; top-arr is the supertype of all function types +(dt top-arr () + [#:frees #f] [#:fold-rhs #:base]) + +;; arities : Listof[arr] +(dt Function (arities) [#:frees (combine-frees (map free-vars* arities)) + (combine-frees (map free-idxs* arities))] + [#:fold-rhs (*Function (map type-rec-id arities))]) + +;; v : Scheme Value +(dt Value (v) [#:frees #f] [#:fold-rhs #:base]) + +;; elems : Listof[Type] +(dt Union (elems) [#:frees (combine-frees (map free-vars* elems)) + (combine-frees (map free-idxs* elems))] + [#:fold-rhs ((unbox union-maker) (map type-rec-id elems))]) + +(dt Univ () [#:frees #f] [#:fold-rhs #:base]) + +;; types : Listof[Type] +(dt Values (types) [#:frees (combine-frees (map free-vars* types)) + (combine-frees (map free-idxs* types))] + [#:fold-rhs (*Values (map type-rec-id types))]) + +;; in : Type +;; out : Type +(dt Param (in out)) + +;; key : Type +;; value : Type +(dt Hashtable (key value)) + +;; t : Type +(dt Syntax (t)) + +;; pos-flds : (Listof Type) +;; name-flds : (Listof (Tuple Symbol Type Boolean)) +;; methods : (Listof (Tuple Symbol Function)) +(dt Class (pos-flds name-flds methods) + [#:frees (combine-frees + (map free-vars* (append pos-flds + (map cadr name-flds) + (map cadr methods)))) + (combine-frees + (map free-idxs* (append pos-flds + (map cadr name-flds) + (map cadr methods))))] - ;; id is an Identifier - (dt Name (id) [#:intern (hash-id id)] [#:frees #f] [#:fold-rhs #:base]) - - ;; rator is a type - ;; rands is a list of types - ;; stx is the syntax of the pair of parens - (dt App (rator rands stx) - [#:intern (list rator rands)] - [#:frees (combine-frees (map free-vars* (cons rator rands))) - (combine-frees (map free-idxs* (cons rator rands)))] - [#:fold-rhs (*App (type-rec-id rator) - (map type-rec-id rands) - stx)]) - - ;; left and right are Types - (dt Pair (left right)) - - ;; elem is a Type - (dt Vector (elem) [#:frees (make-invariant (free-vars* elem)) (make-invariant (free-idxs* elem))]) - - ;; elem is a Type - (dt Box (elem) [#:frees (make-invariant (free-vars* elem)) (make-invariant (free-idxs* elem))]) - - ;; name is a Symbol (not a Name) - (dt Base (name) [#:frees #f] [#:fold-rhs #:base]) - - ;; body is a Scope - (dt Mu (body) #:no-provide [#:frees (free-vars* body) (without-below 1 (free-idxs* body))] - [#:fold-rhs (*Mu (*Scope (type-rec-id (Scope-t body))))]) - - ;; n is how many variables are bound here - ;; body is a Scope - (dt Poly (n body) #:no-provide - [#:frees (free-vars* body) (without-below n (free-idxs* body))] - [#:fold-rhs (let ([body* (remove-scopes n body)]) - (*Poly n (add-scopes n (type-rec-id body*))))]) - - ;; n is how many variables are bound here - ;; there are n-1 'normal' vars and 1 ... var - ;; body is a Scope - (dt PolyDots (n body) #:no-provide - [#:frees (free-vars* body) (without-below n (free-idxs* body))] - [#:fold-rhs (let ([body* (remove-scopes n body)]) - (*PolyDots n (add-scopes n (type-rec-id body*))))]) - - ;; pred : identifier - ;; cert : syntax certifier - (dt Opaque (pred cert) [#:intern (hash-id pred)] [#:frees #f] [#:fold-rhs #:base]) - - ;; name : symbol - ;; parent : Struct - ;; flds : Listof[Type] - ;; proc : Function Type - ;; poly? : is this a polymorphic type? - ;; pred-id : identifier for the predicate of the struct - ;; cert : syntax certifier for pred-id - (dt Struct (name parent flds proc poly? pred-id cert) - [#:intern (list name parent flds proc)] - [#:frees (combine-frees (map free-vars* (append (if proc (list proc) null) (if parent (list parent) null) flds))) - (combine-frees (map free-idxs* (append (if proc (list proc) null) (if parent (list parent) null) flds)))] - [#:fold-rhs (*Struct name - (and parent (type-rec-id parent)) - (map type-rec-id flds) - (and proc (type-rec-id proc)) - poly? - pred-id - cert)]) - - ;; dom : Listof[Type] - ;; rng : Type - ;; rest : Option[Type] - ;; drest : Option[Cons[Type,Name or nat]] - ;; rest and drest NOT both true - ;; thn-eff : Effect - ;; els-eff : Effect - ;; arr is NOT a Type - (dt arr (dom rng rest drest thn-eff els-eff) - [#:frees (combine-frees (append (map flip-variances (map free-vars* (append (if rest (list rest) null) dom))) - (match drest - [(cons t (? symbol? bnd)) - (let ([vs (free-vars* t)]) - (flip-variances (fix-bound vs bnd)))] - [(cons t bnd) (flip-variances (free-vars* t))] - [_ null]) - (list (free-vars* rng)) - (map make-invariant - (map free-vars* (append thn-eff els-eff))))) - (combine-frees (append (map flip-variances (map free-idxs* (append (if rest (list rest) null) dom))) - (match drest - [(cons t (? number? bnd)) - (let ([vs (free-idxs* t)]) - (flip-variances (fix-bound vs bnd)))] - [(cons t bnd) (flip-variances (free-idxs* t))] - [_ null]) - (list (free-idxs* rng)) - (map make-invariant - (map free-idxs* (append thn-eff els-eff)))))] - [#:fold-rhs (*arr (map type-rec-id dom) - (type-rec-id rng) - (and rest (type-rec-id rest)) - (and drest (cons (type-rec-id (car drest)) (cdr drest))) - (map effect-rec-id thn-eff) - (map effect-rec-id els-eff))]) - - ;; top-arr is the supertype of all function types - (dt top-arr () - [#:frees #f] [#:fold-rhs #:base]) - - ;; arities : Listof[arr] - (dt Function (arities) [#:frees (combine-frees (map free-vars* arities)) - (combine-frees (map free-idxs* arities))] - [#:fold-rhs (*Function (map type-rec-id arities))]) - - ;; v : Scheme Value - (dt Value (v) [#:frees #f] [#:fold-rhs #:base]) - - ;; elems : Listof[Type] - (dt Union (elems) [#:frees (combine-frees (map free-vars* elems)) - (combine-frees (map free-idxs* elems))] - [#:fold-rhs ((unbox union-maker) (map type-rec-id elems))]) - - (dt Univ () [#:frees #f] [#:fold-rhs #:base]) - - ;; types : Listof[Type] - (dt Values (types) [#:frees (combine-frees (map free-vars* types)) - (combine-frees (map free-idxs* types))] - [#:fold-rhs (*Values (map type-rec-id types))]) - - ;; in : Type - ;; out : Type - (dt Param (in out)) - - ;; key : Type - ;; value : Type - (dt Hashtable (key value)) - - ;; t : Type - (dt Syntax (t)) - - ;; pos-flds : (Listof Type) - ;; name-flds : (Listof (Tuple Symbol Type Boolean)) - ;; methods : (Listof (Tuple Symbol Function)) - (dt Class (pos-flds name-flds methods) - [#:frees (combine-frees - (map free-vars* (append pos-flds - (map cadr name-flds) - (map cadr methods)))) - (combine-frees - (map free-idxs* (append pos-flds - (map cadr name-flds) - (map cadr methods))))] - - [#:fold-rhs (match (list pos-flds name-flds methods) - [(list - pos-tys - (list (list init-names init-tys) ___) - (list (list mname mty) ___)) - (*Class - (map type-rec-id pos-tys) - (map list - init-names - (map type-rec-id init-tys)) - (map list mname (map type-rec-id mty)))])]) - - ;; cls : Class - (dt Instance (cls)) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;; Ugly hack - should use units - - (define union-maker (box #f)) - - (define (set-union-maker! v) (set-box! union-maker v)) - - (provide set-union-maker!) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;; remove-dups: List[Type] -> List[Type] - ;; removes duplicate types from a SORTED list - (define (remove-dups types) - (cond [(null? types) types] - [(null? (cdr types)) types] - [(type-equal? (car types) (cadr types)) (remove-dups (cdr types))] - [else (cons (car types) (remove-dups (cdr types)))])) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + [#:fold-rhs (match (list pos-flds name-flds methods) + [(list + pos-tys + (list (list init-names init-tys) ___) + (list (list mname mty) ___)) + (*Class + (map type-rec-id pos-tys) + (map list + init-names + (map type-rec-id init-tys)) + (map list mname (map type-rec-id mty)))])]) + +;; cls : Class +(dt Instance (cls)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; Ugly hack - should use units + +(define union-maker (box #f)) + +(define (set-union-maker! v) (set-box! union-maker v)) + +(provide set-union-maker!) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; remove-dups: List[Type] -> List[Type] +;; removes duplicate types from a SORTED list +(define (remove-dups types) + (cond [(null? types) types] + [(null? (cdr types)) types] + [(type-equal? (car types) (cadr types)) (remove-dups (cdr types))] + [else (cons (car types) (remove-dups (cdr types)))])) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; type/effect fold @@ -260,259 +260,274 @@ (values (mk type-name-ht) (mk effect-name-ht)))) (provide type-case effect-case) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ;; sub-eff : (Type -> Type) Eff -> Eff - (define (sub-eff sb eff) - (effect-case sb eff)) - - (define (add-scopes n t) - (if (zero? n) t - (add-scopes (sub1 n) (*Scope t)))) - - (define (remove-scopes n sc) - (if (zero? n) - sc - (match sc - [(Scope: sc*) (remove-scopes (sub1 n) sc*)] - [_ (int-err "Tried to remove too many scopes: ~a" sc)]))) - - ;; abstract-many : Names Type -> Scope^n - ;; where n is the length of names - (define (abstract-many names ty) - (define (nameTo name count type) - (let loop ([outer 0] [ty type]) - (define (sb t) (loop outer t)) - (type-case - sb ty - [#:F name* (if (eq? name name*) (*B (+ count outer)) ty)] - ;; necessary to avoid infinite loops - [#:Union elems (*Union (remove-dups (sort (map sb elems) type Type - ;; where n is the length of types - (define (instantiate-many images sc) - (define (replace image count type) - (let loop ([outer 0] [ty type]) - (define (sb t) (loop outer t)) - (type-case - sb ty - [#:B idx (if (= (+ count outer) idx) - image - ty)] - ;; necessary to avoid infinite loops - [#:Union elems (*Union (remove-dups (sort (map sb elems) type Type - ;; must be applied to a Mu - (define (unfold t) - (match t - [(Mu: sc) (instantiate t sc)] - [_ (int-err "unfold: requires Mu type, got ~a" t)])) - - ;; type equality - (define type-equal? eq?) - ;; inequality - good - - (define (type Type) Eff -> Eff +(define (sub-eff sb eff) + (effect-case sb eff)) + +(define (add-scopes n t) + (if (zero? n) t + (add-scopes (sub1 n) (*Scope t)))) + +(define (remove-scopes n sc) + (if (zero? n) + sc + (match sc + [(Scope: sc*) (remove-scopes (sub1 n) sc*)] + [_ (int-err "Tried to remove too many scopes: ~a" sc)]))) + +;; abstract-many : Names Type -> Scope^n +;; where n is the length of names +(define (abstract-many names ty) + (define (nameTo name count type) + (let loop ([outer 0] [ty type]) + (define (sb t) (loop outer t)) + (type-case + sb ty + [#:F name* (if (eq? name name*) (*B (+ count outer)) ty)] + ;; necessary to avoid infinite loops + [#:Union elems (*Union (remove-dups (sort (map sb elems) type Type +;; where n is the length of types +;; all of the types MUST be Fs +(define (instantiate-many images sc) + (define (replace image count type) + (let loop ([outer 0] [ty type]) + (define (sb t) (loop outer t)) + (type-case + sb ty + [#:B idx (if (= (+ count outer) idx) + image + ty)] + ;; necessary to avoid infinite loops + [#:Union elems (*Union (remove-dups (sort (map sb elems) type Type @@ -35,7 +36,12 @@ (foldr (lambda (e acc) (substitute (cadr e) (car e) acc)) t s)) - +;; unfold : Type -> Type +;; must be applied to a Mu +(define (unfold t) + (match t + [(Mu: name b) (substitute t name b)] + [_ (int-err "unfold: requires Mu type, got ~a" t)])) (define (instantiate-poly t types) (match t