have inst use Any as default type for omitted args

In addition to potentially being convenient, this helps us not
break backwards compatibility when APIs add features that require
additional type variables to properly type.
This commit is contained in:
Andrew Kent 2017-11-10 17:38:57 -05:00 committed by GitHub
parent 4a869d97d1
commit d32218ad15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 35 additions and 16 deletions

View File

@ -555,14 +555,25 @@ protect higher-order uses of the value.
Instantiate the type of @racket[e] with types @racket[t ...] or with the
poly-dotted types @racket[t ... t ooo bound]. @racket[e] must
have a polymorphic type that can be applied to the supplied number of type
variables. This is legal only in expression contexts.
variables. For non-poly-dotted functions, however, fewer arguments can be
provided and the omitted types default to @racket[Any].
@racket[inst] is legal only in expression contexts.
@ex[(foldl (inst cons Integer Integer) null (list 1 2 3 4))
(: fold-list : (All (A) (Listof A) -> (Listof A)))
(define (fold-list lst)
(foldl (inst cons A A) null lst))
(: my-cons (All (A B) (-> A B (Pairof A B))))
(define my-cons cons)
(fold-list (list "1" "2" "3" "4"))
(: foldl-list : (All (α) (Listof α) -> (Listof α)))
(define (foldl-list lst)
(foldl (inst my-cons α (Listof α)) null lst))
(foldl-list (list "1" "2" "3" "4"))
(: foldr-list : (All (α) (Listof α) -> Any))
(define (foldr-list lst)
(foldr (inst my-cons α) null lst))
(foldr-list (list "1" "2" "3" "4"))
(: my-values : (All (A B ...) (A B ... -> (values A B ... B))))
(define (my-values arg . args)
@ -683,7 +694,8 @@ a @racket[require/typed] form. Here is an example of using
so we need to use @racket[case->].
@history[#:changed "1.4" @elem{Added the @racket[#:type-name] option.}
#:changed "1.6" "Added syntax for struct type variables, only works in unsafe requires"]}
#:changed "1.6" "Added syntax for struct type variables, only works in unsafe requires."
#:changed "1.12" @elem{Added default type @racket[Any] for omitted @racket[inst] args.}]}
@defform[(require/typed/provide m rt-clause ...)]{
Similar to @racket[require/typed], but also provides the imported identifiers.

View File

@ -77,11 +77,12 @@
(tc-error/expr #:return -Bottom "Cannot instantiate non-polymorphic type ~a"
(cleanup-type ty))]
[(and (Poly? ty)
(not (= (syntax-length inst) (Poly-n ty))))
(> (syntax-length inst) (Poly-n ty)))
(tc-error/expr #:return -Bottom
"Wrong number of type arguments to polymorphic type ~a:\nexpected: ~a\ngot: ~a"
"Too many type arguments to polymorphic type ~a:\nexpected ~a or fewer\ngot: ~a"
(cleanup-type ty) (Poly-n ty) (syntax-length inst))]
[(and (PolyDots? ty) (not (>= (syntax-length inst) (sub1 (PolyDots-n ty)))))
[(and (PolyDots? ty)
(not (>= (syntax-length inst) (sub1 (PolyDots-n ty)))))
;; we can provide 0 arguments for the ... var
(tc-error/expr #:return -Bottom
"Wrong number of type arguments to polymorphic type ~a:\nexpected at least: ~a\ngot: ~a"

View File

@ -17,10 +17,12 @@
(define (instantiate-poly t types)
(match t
[(Poly: ns body)
(unless (= (length types) (length ns))
(unless (<= (length types) (length ns))
(int-err "instantiate-poly: wrong number of types: expected ~a, got ~a"
(length ns) (length types)))
(subst-all (make-simple-substitution ns types) body)]
;; use Any as the default type for any omitted types
(subst-all (make-simple-substitution ns (list-extend ns types Univ))
body)]
[(PolyDots: (list fixed ... dotted) body)
(unless (>= (length types) (length fixed))
(int-err

View File

@ -246,7 +246,11 @@ at least theoretically.
;; Listof[A] Listof[B] B -> Listof[B]
;; pads out t to be as long as s
(define (list-extend s t extra)
(append t (build-list (max 0 (- (length s) (length t))) (lambda _ extra))))
(define s-len (length s))
(define t-len (length t))
(cond
[(<= s-len t-len) t]
[else (append t (build-list (- s-len t-len) (λ _ extra)))]))
;; does l1 end with l2?
;; e.g. (list 1 2 3) ends with (list 2 3)

View File

@ -1440,10 +1440,10 @@
[tc-e (remf* symbol? '(a b c)) (-lst (one-of/c 'a 'b 'c))]
[tc-e (check-duplicates '("a" "a" "b")) (-opt -String)]
[tc-e (check-duplicates '("a" "a" "b") string=?) (-opt -String)]
;[tc-e ((inst check-duplicates String Number)
; '("a" "aa" "aaa")
; #:key string-length)
; (-opt -String)]
[tc-e ((inst check-duplicates String Number)
'("a" "aa" "aaa")
#:key string-length)
(-opt -String)]
[tc-e ((inst check-duplicates String Any 'nope)
'("a" "a" "b")
string=?