Add for/first/typed and for*/first/typed.

This commit is contained in:
Sergiu Ivanov 2022-06-21 00:42:56 +02:00
parent 1bfc44491e
commit 59b3d5f6fe
2 changed files with 55 additions and 1 deletions

View file

@ -66,6 +66,28 @@ typing} either via a direct @racket[if] check using a predicate, or using
(eval:error (assert-type some-number Zero1)) (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} @section{Hashtable injection}
This section defines some utilities to streamline the usage of hash tables This section defines some utilities to streamline the usage of hash tables

View file

@ -6,7 +6,7 @@
(provide (provide
Variable VariableMapping GeneralPair Variable VariableMapping GeneralPair
assert-type assert-type for/first/typed for*/first/typed
eval-with eval1-with auto-hash-ref/explicit auto-hash-ref/: eval-with eval1-with auto-hash-ref/explicit auto-hash-ref/:
extract-symbols any->string stringify-variable-mapping string->any extract-symbols any->string stringify-variable-mapping string->any
handle-org-booleans map-sexp read-org-sexp unorg unstringify-pairs 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) (define-syntax-parse-rule (assert-type e:expr type:expr)
(assert e (make-predicate type))) (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)) (: eval-with (-> (VariableMapping Any) Any AnyValues))
(define (eval-with ht expr) (define (eval-with ht expr)
(parameterize ([current-namespace (make-base-namespace)]) (parameterize ([current-namespace (make-base-namespace)])