fix vector-map!
to not mutate immutable vectors
This commit is contained in:
parent
c33707329c
commit
903e82731e
|
@ -178,19 +178,15 @@ Applies @racket[proc] to the elements of the @racket[vec]s from the
|
|||
(vector-map + #(1 2) #(3 4))]
|
||||
}
|
||||
|
||||
@defproc[(vector-map! [proc procedure?] [vec vector?] ...+)
|
||||
@defproc[(vector-map! [proc procedure?] [vec (and/c vector? (not/c immutable?))] ...+)
|
||||
vector?]{
|
||||
|
||||
Applies @racket[proc] to the elements of the @racket[vec]s from the
|
||||
first elements to the last. The @racket[proc] argument must accept
|
||||
the same number of arguments as the number of supplied @racket[vec]s,
|
||||
and all @racket[vec]s must have the same number of elements. The
|
||||
each result of @racket[proc] is inserted into the first @racket[vec]
|
||||
at the index that the arguments to @racket[proc] was taken from. The
|
||||
result is the first @racket[vec].
|
||||
Like @racket[vector-map], but result of @racket[proc] is inserted into
|
||||
the first @racket[vec] at the index that the arguments to
|
||||
@racket[proc] were taken from. The result is the first @racket[vec].
|
||||
|
||||
@mz-examples[#:eval vec-eval
|
||||
(define v #(1 2 3 4))
|
||||
(define v (vector 1 2 3 4))
|
||||
(vector-map! add1 v)
|
||||
v
|
||||
]}
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
(let ([vec (vector 1 -2 -3)])
|
||||
(test #(1 2 3) vector-map! (lambda (x y) (max x y)) vec #(0 2 3))
|
||||
(test #(1 2 3) values vec))
|
||||
(err/rt-test (vector-map! add1 #(1)))
|
||||
(err/rt-test (vector-map 1 #()) (check-regs #rx"vector-map" #rx"procedure"))
|
||||
(err/rt-test (vector-map (lambda (x) x) 1) (check-regs #rx"vector-map" #rx"vector"))
|
||||
(err/rt-test (vector-map (lambda (x) x) #() 1) (check-regs #rx"vector-map" #rx"vector"))
|
||||
|
|
|
@ -55,11 +55,15 @@
|
|||
;; that `v' and all the `vs' have the same length
|
||||
;; and that `f' takes |v + vs| args
|
||||
;; uses name for error reporting
|
||||
(define (varargs-check f v vs name)
|
||||
(define (varargs-check f v vs name need-mutable?)
|
||||
(unless (procedure? f)
|
||||
(apply raise-argument-error name "procedure?" 0 f v vs))
|
||||
(unless (vector? v)
|
||||
(apply raise-argument-error name "vector?" 1 f v vs))
|
||||
(unless (and (vector? v)
|
||||
(or (not need-mutable?)
|
||||
(not (immutable? v))))
|
||||
(apply raise-argument-error name
|
||||
(if need-mutable? "(and/c vector? (not/c immutable?))" "vector?")
|
||||
1 f v vs))
|
||||
(let ([len (unsafe-vector-length v)])
|
||||
(for ([e (in-list vs)]
|
||||
[i (in-naturals 2)])
|
||||
|
@ -86,13 +90,13 @@
|
|||
len))
|
||||
|
||||
(define (vector-map f v . vs)
|
||||
(let* ([len (varargs-check f v vs 'vector-map)]
|
||||
(let* ([len (varargs-check f v vs 'vector-map #f)]
|
||||
[new-v (make-vector len)])
|
||||
(vector-map/update f new-v len (cons v vs))
|
||||
new-v))
|
||||
|
||||
(define (vector-map! f v . vs)
|
||||
(define len (varargs-check f v vs 'vector-map!))
|
||||
(define len (varargs-check f v vs 'vector-map! #t))
|
||||
(vector-map/update f v len (cons v vs))
|
||||
v)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user