Add new versions of for/hash: and co that the typechecker can handle.

Based on Eric Dobson's implementation.

Closes PR13248. Closes PR13249.

original commit: 95d51fc8928145fb6f82c8c877e1efcb92432128
This commit is contained in:
Vincent St-Amour 2012-11-20 17:42:16 -05:00
parent c797b00d02
commit c9972ae31c
2 changed files with 113 additions and 7 deletions

View File

@ -0,0 +1,78 @@
#lang typed/racket/base
(require typed/rackunit)
(check-pred
hash?
(for/hash: : (HashTable Integer Symbol)
((a (list 1 2 3)))
(values a 'a)))
(check-pred
hash?
(for/hash: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(check-pred
hash?
(for*/hasheq: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(check-pred
hash-eq?
(for/hasheq: : (HashTable Integer Symbol)
((a (list 1 2 3)))
(values a 'a)))
(check-pred
hash-eq?
(for/hasheq: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(check-pred
hash-eq?
(for*/hasheq: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(check-pred
hash-eqv?
(for/hasheqv: : (HashTable Integer Symbol)
((a (list 1 2 3)))
(values a 'a)))
(check-pred
hash-eqv?
(for/hasheqv: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(check-pred
hash-eqv?
(for*/hasheqv: : (HashTable Integer Symbol)
((a (list 1 2 3))
(b '(a b c)))
(values a b)))
(for*/hash: : (HashTable Number Number)
((v : Number '(1 2 3))
(x : Number '(4 5 6)))
(values v x))
(for/hash: : (HashTable Symbol Symbol)
((v : Symbol '(a b c)))
(values v v))

View File

@ -749,13 +749,10 @@ This file defines two sorts of primitives. All of them are provided into any mod
(quasisyntax/loc
stx
(begin (define-syntax name (define-for-variant #'untyped-name)) ...))]))
;; for/hash{,eq,eqv}:, for/vector:, for/flvector:, for/and:, for/first: and
;; for/vector:, for/flvector:, for/and:, for/first: and
;; for/last:'s expansions can't currently be handled by the typechecker.
(define-for-variants
(for/list: for/list)
(for/hash: for/hash)
(for/hasheq: for/hasheq)
(for/hasheqv: for/hasheqv)
(for/and: for/and)
(for/or: for/or)
(for/first: for/first)
@ -842,9 +839,6 @@ This file defines two sorts of primitives. All of them are provided into any mod
...))]))
(define-for*-variants
(for*/list: for*/list)
(for*/hash: for*/hash)
(for*/hasheq: for*/hasheq)
(for*/hasheqv: for*/hasheqv)
(for*/and: for*/and)
(for*/or: for*/or)
(for*/first: for*/first)
@ -924,6 +918,40 @@ This file defines two sorts of primitives. All of them are provided into any mod
...))]))
(define-for/sum:-variants (for/sum: for/fold:) (for*/sum: for*/fold:))
(define-for-syntax (define-for/hash:-variant hash-maker)
(lambda (stx)
(syntax-parse stx
#:literals (:)
((_ (~seq : return-annotation:expr)
(bind:optionally-annotated-binding ...) body:expr ...)
(quasisyntax/loc stx
(for/fold: : return-annotation
((return-hash : return-annotation (ann (#,hash-maker null) return-annotation)))
(bind ...)
(let-values (((key val) (let () body ...)))
(hash-set return-hash key val))))))))
(define-syntax for/hash: (define-for/hash:-variant #'make-immutable-hash))
(define-syntax for/hasheq: (define-for/hash:-variant #'make-immutable-hasheq))
(define-syntax for/hasheqv: (define-for/hash:-variant #'make-immutable-hasheqv))
(define-for-syntax (define-for*/hash:-variant hash-maker)
(lambda (stx)
(syntax-parse stx
#:literals (:)
((_ (~seq : return-annotation:expr)
(bind:optionally-annotated-binding ...) body:expr ...)
(quasisyntax/loc stx
(for*/fold: : return-annotation
((return-hash : return-annotation (ann (#,hash-maker null) return-annotation)))
(bind ...)
(let-values (((key val) (let () body ...)))
(hash-set return-hash key val))))))))
(define-syntax for*/hash: (define-for*/hash:-variant #'make-immutable-hash))
(define-syntax for*/hasheq: (define-for*/hash:-variant #'make-immutable-hasheq))
(define-syntax for*/hasheqv: (define-for*/hash:-variant #'make-immutable-hasheqv))
(define-syntax (provide: stx)
(syntax-parse stx