Wrote tests for the for: macros.
This commit is contained in:
parent
49caa00890
commit
c92ae73859
115
collects/tests/typed-scheme/succeed/for.rkt
Normal file
115
collects/tests/typed-scheme/succeed/for.rkt
Normal file
|
@ -0,0 +1,115 @@
|
|||
#lang typed/scheme
|
||||
|
||||
(: check (All (a) ((a a -> Boolean) a a -> Boolean)))
|
||||
;; Simple check function as RackUnit doesn't work in Typed Scheme (yet)
|
||||
(define (check f a b)
|
||||
(if (f a b)
|
||||
#t
|
||||
(error (format "Check (~a ~a ~a) failed" f a b))))
|
||||
|
||||
(check string=?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(for: : Void ([i : Integer (in-range 10)])
|
||||
(display i))))
|
||||
"0123456789")
|
||||
|
||||
(check string=?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(for: : Void
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Char "abc")
|
||||
#:when (odd? i)
|
||||
(k : True #(#t #t))
|
||||
#:when k)
|
||||
(display (list i j k)))))
|
||||
"(1 a #t)(1 a #t)(3 c #t)(3 c #t)")
|
||||
|
||||
(check equal?
|
||||
(for/list: : (Listof Integer) ([i : Integer (in-range 10)]) i)
|
||||
'(0 1 2 3 4 5 6 7 8 9))
|
||||
|
||||
(check equal?
|
||||
(for/list: : (Listof Integer)
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30))
|
||||
#:when (odd? i))
|
||||
(+ i j 10))
|
||||
'(21 43))
|
||||
|
||||
(check equal?
|
||||
(for/or: : Boolean
|
||||
((i : Exact-Positive-Integer '(1 2 3)))
|
||||
(>= i 3))
|
||||
#t)
|
||||
|
||||
(check equal?
|
||||
(for/or: : Boolean
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(2 1 3)))
|
||||
(>= i j))
|
||||
#t)
|
||||
|
||||
(check equal?
|
||||
(let-values: ([([x : (Listof Integer)] [y : (Listof Integer)])
|
||||
(for/lists: : (values (Listof Integer) (Listof Integer))
|
||||
((x : (Listof Integer))
|
||||
(y : (Listof Integer)))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
#:when #t
|
||||
(j : Exact-Positive-Integer '(10 20 30))
|
||||
#:when (> j 12))
|
||||
(values i j))])
|
||||
(append x y))
|
||||
'(1 1 2 2 3 3 20 30 20 30 20 30))
|
||||
|
||||
(check =
|
||||
(for/fold: : Integer
|
||||
((acc : Integer 0))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(+ acc i j))
|
||||
66)
|
||||
|
||||
(check =
|
||||
(for/fold: : Integer
|
||||
((acc : Integer 0))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
#:when (even? i)
|
||||
(j : Exact-Positive-Integer '(10 20 30))
|
||||
#:when #t
|
||||
(k : Exact-Positive-Integer '(100 200 300)))
|
||||
(+ acc i j k))
|
||||
1998)
|
||||
|
||||
(check string=?
|
||||
(with-output-to-string
|
||||
(lambda ()
|
||||
(for*: : Void
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(display (list i j)))))
|
||||
"(1 10)(1 20)(1 30)(2 10)(2 20)(2 30)(3 10)(3 20)(3 30)")
|
||||
|
||||
(check equal?
|
||||
(let-values: ([([x : (Listof Integer)] [y : (Listof Integer)])
|
||||
(for*/lists: : (values (Listof Integer) (Listof Integer))
|
||||
((x : (Listof Integer))
|
||||
(y : (Listof Integer)))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30))
|
||||
#:when (> j 12))
|
||||
(values i j))])
|
||||
(append x y))
|
||||
'(1 1 2 2 3 3 20 30 20 30 20 30))
|
||||
|
||||
(check =
|
||||
(for*/fold: : Integer
|
||||
((acc : Integer 0))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
#:when (even? i)
|
||||
(j : Exact-Positive-Integer '(10 20 30))
|
||||
(k : Exact-Positive-Integer '(100 200 300)))
|
||||
(+ acc i j k))
|
||||
1998)
|
55
collects/tests/typed-scheme/xfail/for-inference.rkt
Normal file
55
collects/tests/typed-scheme/xfail/for-inference.rkt
Normal file
|
@ -0,0 +1,55 @@
|
|||
#lang typed/scheme
|
||||
|
||||
;; Inference fails when #:when clauses are used, except when there's
|
||||
;; only one, and it's the last clause.
|
||||
;; for:, for*: are unaffected, since they currently expand their
|
||||
;; #:when clauses manually, unlike for/list: and co, who punt it to
|
||||
;; non-annotated versions of the macros, to avoid breaking semantics.
|
||||
;; for/fold:, for*/fold:, for/lists: and for*/lists: are not affected
|
||||
;; either. The inferencer can handle their expansion, apparently no
|
||||
;; matter how many #:when clauses we throw at them.
|
||||
;; Of course, for*/list: and co won't work, since they are equivalent
|
||||
;; to for/list: and co with #:when clauses.
|
||||
(for/list: : (Listof Integer)
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
#:when (odd? i)
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(+ i j 10))
|
||||
|
||||
(for/list: : (Listof Integer)
|
||||
(#:when #t
|
||||
(i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(+ i j 10))
|
||||
|
||||
(for*/list: : (Listof (Listof Integer))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(list i j))
|
||||
|
||||
;; The right type for the return value would be (values (Listof Integer) (Listof Integer)).
|
||||
;; The problem here is with the error message. Somehow, source location information is lost and the whole module is blamed.
|
||||
(for/lists: : (Listof Integer)
|
||||
((x : (Listof Integer))
|
||||
(y : (Listof Integer)))
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(values i j))
|
||||
|
||||
;; This is a legitimate use of multi-valued seq-exprs, but it causes the typechecker to throw an internal error.
|
||||
(for/list: : (Listof Integer)
|
||||
((([i : Exact-Positive-Integer]
|
||||
[j : Exact-Positive-Integer])
|
||||
(list (values 1 10) (values 2 20) (values 2 30)))
|
||||
#:when (odd? i))
|
||||
(+ i j 10))
|
||||
|
||||
;; Types can't be inferred for the expansion of for/first: at all.
|
||||
(for/first: : Integer
|
||||
((i : Exact-Positive-Integer '(1 2 3)))
|
||||
i)
|
||||
|
||||
;; Same for for/last:
|
||||
(for/last: : (Option Integer)
|
||||
((i : Exact-Positive-Integer '(1 2 3)))
|
||||
i)
|
37
collects/tests/typed-scheme/xfail/for-type-precision.rkt
Normal file
37
collects/tests/typed-scheme/xfail/for-type-precision.rkt
Normal file
|
@ -0,0 +1,37 @@
|
|||
#lang typed/scheme
|
||||
|
||||
;; I would have to be annotated with its most precise type (Exact-Positive-Integer) for this to work
|
||||
(for: : Void ((i : Integer '(1 2 3)))
|
||||
(display i))
|
||||
|
||||
;; same here, would need type (U (List 'a 't) (List 'c 'g))
|
||||
(for: : Void
|
||||
([from-to : (List Symbol Symbol)
|
||||
'([a t]
|
||||
[c g])])
|
||||
#t)
|
||||
|
||||
;; wants (U False True), which should be the same as Boolean, but apparently isn't
|
||||
(for: : Void
|
||||
((k : Boolean #(#t #f))
|
||||
#:when k)
|
||||
(display k))
|
||||
|
||||
;; unlike the usual cases with #:when clauses (see for-inference.rkt), inference does something, but does it wrong
|
||||
(for/list: : (Listof Integer)
|
||||
(#:when #t
|
||||
(i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Exact-Positive-Integer '(10 20 30)))
|
||||
(+ i j 10))
|
||||
|
||||
;; that same bug makes for/hash:, for/hasheq: and for/hasheqv: unusable
|
||||
;; this infers Nothing for the type of the elements of the HashTable
|
||||
;; since they don't work, these functions are not currently documented
|
||||
(for/hash: : (HashTable Integer Char)
|
||||
((i : Exact-Positive-Integer '(1 2 3))
|
||||
(j : Char "abc"))
|
||||
(values i j))
|
||||
;; same thing for for/and:
|
||||
(for/and: : Boolean
|
||||
((i : Exact-Positive-Integer '(1 2 3)))
|
||||
(< i 3))
|
Loading…
Reference in New Issue
Block a user