It's unlikely that an implementation using continuations would be
faster than one that does not.

An idiomatic solution might look like:

(define (map-once fn xs)
  (for/list ([i (in-range (length xs))])
    (for/list ([(x j) (in-indexed (in-list xs))])
      (cond [(= i j) (fn x)]
            [else x]))))


But it's not terribly fast.
If you're willing to use vectors instead of lists, then maybe:

(define (map-once fn xs)
  (build-vector (vector-length xs)
                (λ (i)
                  (define v (vector-copy xs))
                  (vector-set! v i (fn (vector-ref v i)))
                  v)))


On Fri, Jun 19, 2015 at 3:24 PM, Luke Miles <rashreportl...@gmail.com> wrote:
> Say I have a list ls and I want to produce a list of
> lists where the i'th list has the i'th element of ls tripled,
> but all other elements are the same.
>
> e.g. '(3 5 7) => '((9 5 7) (3 15 7) (3 5 21))
>
> What is a fast way to do this?
>
>
> I could do a loop with appending.
> (define (map-once f ls)
>   (let M ([sooner null] [later ls])
>     (if (null? later) null
>       (cons (append sooner (list (f (car later))) (cdr later))
>             (M (append sooner (list (car later))) (cdr later))))))
>
> -> (map-once sqr '(4 5 6))
> '((16 5 6) (4 25 6) (4 5 36))
>
> Unfortunately, this is very slow & messy.
> I have to do 2 big appends for every element is the return list.
>
>
> Here is a cleaner-looking, but still slow way:
> (define (list-set ls i new-val)
>   (let-values ([(sooner later) (split-at ls i)])
>     (append sooner (list new-val) (cdr later))))
>
> (define (map-once f ls)
>   (for/list ([i (in-naturals)]
>              [elm (in-list ls)])
>     (list-set ls i (f elm))))
>
>
> I'm thinking a good implementation might use continuations somehow?
>
> Maybe of vector-set (without the exclamation point) existed, I could use it?
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to