[racket] Building an indexing function for lists-of-lists

From: Daniel Prager (daniel.a.prager at gmail.com)
Date: Mon Jan 13 19:06:08 EST 2014

Hi Rian

> are there are any built-in functions that I can take advantage of to make
this function cleaner?

I'm not aware of a built-in function to help, but sometimes it's quite easy
to abstract upwards and write your own.

In this case a generalization to map for trees that preserves structure
looks about right:

;; Apply f to every atom in 'tree', preserving the list-y structure.
;;
(define (tree-map f tree)
  (define (T t)
    (cond [(empty? t) empty]
          [(atom? (first t)) (cons (f (first t)) (T (rest t)))]
          [else (cons (T (first t)) (T (rest t)))]))
  (T tree))

> (tree-map (λ (x) '*) '(+ (- .1 .2) .3))
'(* (* * *) *)

Then instead of mapping to an asterisk, you can use an incrementing counter:

(define (make-counter from)
  (let ([index from])
    (λ ()
      (let ([result index])
        (set! index (add1 index))
        result))))

> (define c (make-counter 1))
> (c)
1
> (c)
2

Now you can write your indexing function succinctly:

(define (index-s-exp s-exp index)
  (let ([c (make-counter index)])
    (tree-map (λ (x) (c)) s-exp)))


Aside: This is a less pure solution compared to Matthias's, since it makes
use of state in the counter.


Dan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140114/b363f4a8/attachment.html>

Posted on the users mailing list.