user5690367
user5690367

Reputation:

Racket: Write a function to access a component of a structure

I want to abstract the following functions:

(define (road_length1 n)
  (road-length (node-road1 n)))
(define (road_length2 n)
  (road-length (node-road2 n)))
(define (road_length3 n)
  (road-length (node-road3 n)))

My structures for a node and road are like this:

  (define-struct node [Letter road1 road2 road3])
  (define-struct road [name length])

Hence I want to be able to access the length of a given road from a node, like this:

 (define (road_length n road_number)
    (road-length (node-(road_number) n)))

However this doesn't work

Upvotes: 1

Views: 122

Answers (2)

Sylwester
Sylwester

Reputation: 48745

I personally feel the fact the roads are numbered is smelling pretty bad already. I would have changed it to this:

(define-struct node [letter roads] #:constructor-name make-raw-node)
(define (make-node letter . roads)
  (make-raw-node letter (list->vector roads)))

(define (node-road-length node road-index)
  (road-length (vector-ref (node-roads node) road-index)))

Note that in sane programming languages we start indexing elements from 0 so road-number is in the range [0,2].

If you really want to have the indexes in the names, then you make a map between the indexes and their accessors:

(define node-road-length
  (let ((lookup (vector node-road1 
                        node-road2 
                        node-road3)))
    (lambda (node road-index)
      (road-length ((lookup road-index) node)))))

Upvotes: 0

Leif Andersen
Leif Andersen

Reputation: 22332

Probably the easiest way is for you to store your nodes in either a vector or list

To do this, I would just store it in your struct like this:

(struct node (letter roads))

(As a side note, struct is a better (or at least newer) way to create a struct, than define-struct.)

Once you do that, you can pass in the index of the road you want as a paramter to the function.

(define (road-length node road)
  (list-ref (node-roads node) road))

(I should note that there is 'technically' a way to do exactly what you want here with macros, but I'm almost certain that it would be overkill in this situation, when functions work just fine.)

Upvotes: 2

Related Questions