如何在Racket中返回参数值?

时间:2013-12-25 09:59:55

标签: scheme return racket reverse

我必须创建一个返回列表反向的Racket方案。我不能使用内置的反向方法或类似的东西。 到目前为止,我已经做了一切可以逆转,但问题是我的方法没有返回值,而是保留它。 这就是我所做的:

#lang racket

(define (rev x) 
  (define n '())
  (define i (- (length x) 1))
  (let loop ()
    (when (> i -1)
      (set! n (append n (list (list-ref x i))))
      (set! i (sub1 i))
      (loop)))
  (set! x n)
  "in method display"
  (displayln x))

"display"
(define letters'("a" "b" "c"))
(rev letters)
"in main program display"
(displayln letters)

当我在方法中打印时,我得到(c b a)但是当我从主程序打印时,我得到(a b c)这意味着我的方法没有返回值。我该怎么办?

此方法返回void,如何使其返回值?

1 个答案:

答案 0 :(得分:3)

在一个过程中评估的最后一个表达式是“返回”的内容,因此在rev中它是(displayln x)并且它返回一个void。如果您将最后一个元素更改为n:

(define (rev x) 
  (define n '())
  (define i (- (length x) 1))
  (let loop ()
    (when (> i -1)
      (set! n (append n (list (list-ref x i))))
      (set! i (sub1 i))
      (loop)))
  (set! x n)
  "in method display"
  (displayln x)
  n) ; evaluates n last!

它也会返回结果。这个代码对于Scheme来说是非常必要的。在不改变解决方法的情况下,您可以将ni移至指定的let

(define (rev x) 
  (let loop ((n '())
             (i (- (length x) 1)))
    (if (> i -1)                             ; if i is positive
      (loop (append n (list (list-ref x i))) ; then call loop with new n and
            (sub1 i))                        ; new i
      n)))                                   ; else return n

更惯用的解决方案是cons从开始到结束的元素到累加器。第一个元素将自动成为最后一个元素:

(define (rev lst)
  (let loop ((lst lst)                 ; we start with the whole list
             (acc '()))                ; out initial acc is the empty list
    (if (<??> lst)                     ; if lst is empty
        <??>                           ; then return accumulator 
        (loop (<??> lst)               ; else we recurse with the cdr of the list
              (cons <??> acc)))))      ; while adding the car to the beginning of acc