support exact nonnegative integers as sequences
This commit is contained in:
parent
4e576a8ac9
commit
e0d26d88b6
|
@ -424,7 +424,8 @@
|
|||
v)))
|
||||
|
||||
(define (sequence? v)
|
||||
(or (do-sequence? v)
|
||||
(or (exact-nonnegative-integer? v)
|
||||
(do-sequence? v)
|
||||
(sequence-via-prop? v)
|
||||
(stream? v)
|
||||
(mpair? v)
|
||||
|
@ -437,6 +438,7 @@
|
|||
|
||||
(define (make-sequence who v)
|
||||
(cond
|
||||
[(exact-nonnegative-integer? v) (:integer-gen v)]
|
||||
[(do-sequence? v) ((do-sequence-ref v 0))]
|
||||
[(mpair? v) (:mlist-gen v)]
|
||||
[(list? v) (:list-gen v)]
|
||||
|
@ -498,6 +500,9 @@
|
|||
[inc (lambda (x) (+ x step))])
|
||||
(make-range a inc cont?))]))
|
||||
|
||||
(define (:integer-gen v)
|
||||
(values values add1 0 (lambda (i) (i . < . v)) #f #f))
|
||||
|
||||
(define in-naturals
|
||||
(case-lambda
|
||||
[() (in-naturals 0)]
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
(cond
|
||||
[(zero? i) seq]
|
||||
[(stream? seq) (stream-tail seq i)]
|
||||
[(exact-nonnegative-integer? seq) (stream-tail (in-range seq) i)]
|
||||
[else
|
||||
(make-do-sequence
|
||||
(lambda ()
|
||||
|
|
|
@ -29,6 +29,8 @@ the @racket[_body]s for side effects.
|
|||
(display i))
|
||||
(for ([i "abc"])
|
||||
(printf "~a..." i))
|
||||
(for ([i 4])
|
||||
(display i))
|
||||
]
|
||||
|
||||
The @racket[for/list] variant of @racket[for] is more Racket-like. It
|
||||
|
@ -42,6 +44,8 @@ comprehension}.
|
|||
(* i i))
|
||||
(for/list ([i "abc"])
|
||||
i)
|
||||
(for/list ([i 4])
|
||||
i)
|
||||
]
|
||||
|
||||
The full syntax of @racket[for] accommodates multiple sequences to
|
||||
|
@ -59,9 +63,12 @@ see the kinds of sequence generators that make interesting examples.
|
|||
The @racket[in-range] function generates a sequence of numbers, given
|
||||
an optional starting number (which defaults to @racket[0]), a number
|
||||
before which the sequences ends, and an optional step (which defaults
|
||||
to @racket[1]).
|
||||
to @racket[1]). Using a non-negative integer @racket[_k] directly as
|
||||
a sequence is a shorthand for @racket[(in-range _k)].
|
||||
|
||||
@examples[
|
||||
(for ([i 3])
|
||||
(display i))
|
||||
(for ([i (in-range 3)])
|
||||
(display i))
|
||||
(for ([i (in-range 1 4)])
|
||||
|
@ -102,7 +109,8 @@ true.
|
|||
|
||||
Sequence constructors like @racket[in-list], @racket[in-vector] and
|
||||
@racket[in-string] simply make explicit the use of a list, vector, or
|
||||
string as a sequence. Since they raise an exception when given the
|
||||
string as a sequence. Along with @racket[in-range],
|
||||
these constructors raise an exception when given the
|
||||
wrong kind of value, and since they otherwise avoid a run-time
|
||||
dispatch to determine the sequence type, they enable more efficient
|
||||
code generation; see @secref["for-performance"] for more information.
|
||||
|
@ -425,7 +433,8 @@ fast-clause [id fast-seq]
|
|||
|
||||
@racketgrammar[
|
||||
#:literals [in-range in-naturals in-list in-vector in-string in-bytes in-value stop-before stop-after]
|
||||
fast-seq (in-range expr expr)
|
||||
fast-seq (in-range expr)
|
||||
(in-range expr expr)
|
||||
(in-range expr expr expr)
|
||||
(in-naturals)
|
||||
(in-naturals expr)
|
||||
|
|
|
@ -35,6 +35,8 @@ built-in datatypes, the sequence datatype includes the following:
|
|||
|
||||
@itemize[
|
||||
|
||||
@item{exact nonnegative integers (see below)}
|
||||
|
||||
@item{strings (see @secref["strings"])}
|
||||
|
||||
@item{byte strings (see @secref["bytestrings"])}
|
||||
|
@ -57,6 +59,10 @@ built-in datatypes, the sequence datatype includes the following:
|
|||
|
||||
]
|
||||
|
||||
An @tech{exact number} @racket[_k] that is a non-negative
|
||||
@tech{integer} acts as a sequence similar to @racket[(in-range _k)],
|
||||
except that @racket[_k] by itself is not a @tech{stream}.
|
||||
|
||||
The @scheme[make-do-sequence] function creates a sequence given a
|
||||
thunk that returns procedures to implement a sequence, and the
|
||||
@scheme[prop:sequence] property can be associated with a structure
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
(require racket/mpair
|
||||
"for-util.rkt")
|
||||
|
||||
(test-sequence [(0 1 2)] 3)
|
||||
(test-sequence [(0 1 2)] (in-range 3))
|
||||
(test-sequence [(3 4 5)] (in-range 3 6))
|
||||
(test-sequence [(7 6 5)] (in-range 7 4 -1))
|
||||
(test-sequence [(3.0 4.0 5.0)] (in-range 3.0 6.0))
|
||||
(test-sequence [(3.0 3.5 4.0 4.5 5.0 5.5)] (in-range 3.0 6.0 0.5))
|
||||
(test-sequence [(3.0 3.1 3.2)] (in-range 3.0 3.3 0.1))
|
||||
|
||||
(test-sequence [(a b c)] '(a b c))
|
||||
(test-sequence [(a b c)] (in-list '(a b c)))
|
||||
|
@ -228,7 +232,7 @@
|
|||
(test 13 next)
|
||||
(test #f more?))
|
||||
|
||||
;; check ranges on `in-vetcor', especially as a value
|
||||
;; check ranges on `in-vector', especially as a value
|
||||
(test '() 'in-empty-vector (let ([v (in-vector '#())]) (for/list ([e v]) e)))
|
||||
(test '() 'in-empty-vector (let ([v (in-vector '#() 0)]) (for/list ([e v]) e)))
|
||||
(test '() 'in-empty-vector (let ([v (in-vector '#() 0 0)]) (for/list ([e v]) e)))
|
||||
|
|
|
@ -29,21 +29,23 @@
|
|||
|
||||
(test '(0 1 2) 'sequence->list (sequence->list (in-range 3)))
|
||||
(arity-test sequence->list 1 1)
|
||||
(err/rt-test (sequence->list 1))
|
||||
(err/rt-test (sequence->list 'a))
|
||||
|
||||
(test '() 'empty-sequence (sequence->list empty-sequence))
|
||||
|
||||
(arity-test sequence-length 1 1)
|
||||
(err/rt-test (sequence-length 1))
|
||||
(err/rt-test (sequence-length 'a))
|
||||
(test 3 'sequence-length (sequence-length (in-range 3)))
|
||||
|
||||
(arity-test sequence-ref 2 2)
|
||||
(err/rt-test (sequence-ref 2 0))
|
||||
(err/rt-test (sequence-ref 'a 0))
|
||||
(err/rt-test (sequence-ref (in-naturals) -1) exn:fail?)
|
||||
(err/rt-test (sequence-ref (in-naturals) 1.0) exn:fail?)
|
||||
(test 0 'sequence-ref (sequence-ref (in-naturals) 0))
|
||||
(test 1 'sequence-ref (sequence-ref (in-naturals) 1))
|
||||
(test 25 'sequence-ref (sequence-ref (in-naturals) 25))
|
||||
(when (sequence? 10)
|
||||
(test 3 sequence-ref 10 3))
|
||||
|
||||
(arity-test sequence-tail 2 2)
|
||||
(err/rt-test (sequence-tail (in-naturals) -1) exn:fail?)
|
||||
|
@ -51,14 +53,18 @@
|
|||
(test 4 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 0))
|
||||
(test 5 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 1))
|
||||
(test 29 'sequence-ref (sequence-ref (sequence-tail (in-naturals) 4) 25))
|
||||
(when (sequence? 10)
|
||||
(test 29 'sequence-ref (sequence-ref (sequence-tail 100 4) 25)))
|
||||
|
||||
;; XXX Check for rest
|
||||
(err/rt-test (sequence-append 1) exn:fail?)
|
||||
(err/rt-test (sequence-append (in-naturals) 1) exn:fail?)
|
||||
(err/rt-test (sequence-append 'a) exn:fail?)
|
||||
(err/rt-test (sequence-append (in-naturals) 'a) exn:fail?)
|
||||
(test '() 'sequence-append (sequence->list (sequence-append)))
|
||||
(test 5 'sequence-append (sequence-ref (sequence-append (in-naturals)) 5))
|
||||
(test 5 'sequence-append
|
||||
(sequence-ref (sequence-append (in-range 3) (in-range 3 10)) 5))
|
||||
(when (sequence? 10)
|
||||
(test 5 sequence-ref (sequence-append 4 10) 9))
|
||||
|
||||
(arity-test sequence-map 2 2)
|
||||
(err/rt-test (sequence-map 2 (in-naturals)) exn:fail?)
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
Version 5.1.1.2
|
||||
Changed "sequence" to include exact nonnegative integers
|
||||
|
||||
Version 5.1.1, May 2011
|
||||
Enabled single-precision floats by default
|
||||
Added single-flonum?
|
||||
|
|
Loading…
Reference in New Issue
Block a user