Add for/first/typed and for*/first/typed.
This commit is contained in:
parent
1bfc44491e
commit
59b3d5f6fe
2 changed files with 55 additions and 1 deletions
|
@ -66,6 +66,28 @@ typing} either via a direct @racket[if] check using a predicate, or using
|
|||
(eval:error (assert-type some-number Zero1))
|
||||
]}
|
||||
|
||||
@deftogether[(@defform[(for/first/typed type-ann (for-clause ...) expr ...+)])
|
||||
@defform[(for*/first/typed type-ann (for-clause ...) expr ...+)]]{
|
||||
|
||||
Typed versions of @racket[for/first] and @racket[for*/first].
|
||||
|
||||
@ex[
|
||||
(for/first/typed : (Option Integer)
|
||||
([i (in-range 1 10)]
|
||||
#:when (zero? (modulo i 5)))
|
||||
(* i 3))
|
||||
(for*/first/typed : (Option (Pairof Integer Integer))
|
||||
([i (in-range 1 10)]
|
||||
[j (in-range 1 10)]
|
||||
#:when (> (+ i j) 5))
|
||||
(cons i j))
|
||||
]
|
||||
|
||||
The implementation of these macros is a simplified version the definition of
|
||||
@hyperlink["https://github.com/racket/typed-racket/blob/9d3264c97aa63b6a7163a219937b88a612add8ab/typed-racket-lib/typed-racket/base-env/prims.rkt#L512"]{@racket[define-for/acc:-variant]}.
|
||||
|
||||
}
|
||||
|
||||
@section{Hashtable injection}
|
||||
|
||||
This section defines some utilities to streamline the usage of hash tables
|
||||
|
|
34
utils.rkt
34
utils.rkt
|
@ -6,7 +6,7 @@
|
|||
(provide
|
||||
Variable VariableMapping GeneralPair
|
||||
|
||||
assert-type
|
||||
assert-type for/first/typed for*/first/typed
|
||||
eval-with eval1-with auto-hash-ref/explicit auto-hash-ref/:
|
||||
extract-symbols any->string stringify-variable-mapping string->any
|
||||
handle-org-booleans map-sexp read-org-sexp unorg unstringify-pairs
|
||||
|
@ -29,6 +29,38 @@
|
|||
(define-syntax-parse-rule (assert-type e:expr type:expr)
|
||||
(assert e (make-predicate type)))
|
||||
|
||||
(define-for-syntax (make-for/first/typed-variant folder)
|
||||
(syntax-parser
|
||||
#:literals (:)
|
||||
[(_ :
|
||||
ty:expr ; These should probably be more specific.
|
||||
clauses:expr
|
||||
c ...)
|
||||
#`(#,folder : ty
|
||||
([result : ty #f])
|
||||
clauses
|
||||
#:break (not (equal? result #f))
|
||||
c ...)]))
|
||||
|
||||
(define-syntax for/first/typed (make-for/first/typed-variant 'for/fold))
|
||||
(define-syntax for*/first/typed (make-for/first/typed-variant 'for*/fold))
|
||||
|
||||
(module+ test
|
||||
(test-case "for/first/typed, for/first/typed*"
|
||||
(check-equal? (for/first/typed : (Option Integer)
|
||||
([i (in-range 1 10)]
|
||||
#:when (zero? (modulo i 5)))
|
||||
(* i 3))
|
||||
15)
|
||||
(check-equal? (for*/first/typed : (Option (Pairof Integer Integer))
|
||||
([i (in-range 1 10)]
|
||||
[j (in-range 1 10)]
|
||||
#:when (> (+ i j) 5)
|
||||
#:when (even? i)
|
||||
#:when (even? j))
|
||||
(cons i j))
|
||||
'(2 . 4))))
|
||||
|
||||
(: eval-with (-> (VariableMapping Any) Any AnyValues))
|
||||
(define (eval-with ht expr)
|
||||
(parameterize ([current-namespace (make-base-namespace)])
|
||||
|
|
Loading…
Reference in a new issue