How to change the order of list items in a diagram

I got a function to change the order of items in a list like

(define (rvsl sequence)
  (foldl (lambda (x y) 
           (cons y x)) 
         '() sequence))

      

However, when I run it in DrRacket with input

(rvsl (list 2 3 4))

      

DrRacket told me this

cons: second argument must be a list, but received empty and 2

      

Can someone please give me some ideas to solve this problem?

Thanks in advance!

+3


source to share


3 answers


The problem with your code is that you are passing parameters in the wrong order - when used cons

to create a list, the first parameter is a new item that we want to stick to at the beginning of the list, and the second is the list we have created so far.

Having said that, changing a list with a is a foldl

little easier and you don't need to use append

at all - in fact, it's bad practice to use append

when cons

enough:

(define (rvsl sequence)
  (foldl cons
         '()
         sequence))

      

Why does it work? let's rewrite the function more explicit this time:



(define (rvsl sequence)
  (foldl (lambda (current accumulated)
           (cons current accumulated))
         '()
         sequence))

      

Now we can see that the procedure lambda

takes two parameters: the element current

in the input list and the value accumulated

so far - good parameter names make all the difference in the world! this is much, much clearer than calling parameters x

and y

that don't say anything about them.

In this case, we just want the cons

current item to be at the head of the accumulated value (which starts out as an empty list), hence creating a reverse list as output. Given that the procedure lambda

takes two parameters and passes them in the same order as and cons

, we can simplify the whole thing and just pass the procedure cons

as a parameter.

+2


source


Here's a simple version using an internal iterative procedure.



(define (rev lst)
  (define (iter accum lst)
    (if (null? lst)
        accum
        (iter (cons (car lst) accum)
              (cdr lst))))
  (iter '() lst))

      

+1


source


You don't need to use foldl

or anything else to define the function rev

; the function itself is rev

enough:

(define (rev ls)                                 ; rev [] = []
  (cond                                          ; rev [x] = [x]
    ((null? ls) ls)                              ; rev (x:xs) 
    ((null? (rest ls)) ls)                       ;   | (a:b) <- rev xs 
    (else                                        ;   = a : rev (x : rev b)
      (cons (first (rev (rest ls)))
            (rev (cons (first ls)
                       (rev (rest (rev (rest ls))))))))))

      

(comments in pseudocode for matching equivalent patterns). Conclusion and discussion here .

(edit: this is obviously toy code, just to hone your Scheme-fu).

0


source







All Articles