Scheme 在方案中进行迭代循环

Scheme 在方案中进行迭代循环,scheme,racket,Scheme,Racket,我对scheme很陌生,在学习do循环时遇到了一些问题。我试图创建一个函数,该函数将接受一个对象和一个向量,然后遍历该向量,直到找到该对象为止。找到该对象后,它将返回一个列表,其中包含该对象之前向量中的所有项。我的代码如下。它只会返回do循环经过了多少次迭代,而不是我想要的列表。如果有人能帮我学习语法,我将不胜感激。谢谢(理想情况下,这将返回(12)) (定义(向量测试迭代X向量) (do((i0(+i1))(

我对scheme很陌生,在学习do循环时遇到了一些问题。我试图创建一个函数,该函数将接受一个对象和一个向量,然后遍历该向量,直到找到该对象为止。找到该对象后,它将返回一个列表,其中包含该对象之前向量中的所有项。我的代码如下。它只会返回do循环经过了多少次迭代,而不是我想要的列表。如果有人能帮我学习语法,我将不胜感激。谢谢(理想情况下,这将返回(12))

(定义(向量测试迭代X向量)
(do((i0(+i1))(
如果您使用的是Racket,那么就没有必要使用
do
,这在Schemer中从来都不流行。迭代器的范围很广——在文档中查找
for
,以及以
for
开头的迭代器。例如,您的代码可以归结为

#lang racket
(define (values-before x vector)
  (for/list ([y (stop-before (in-vector vector)
                             (lambda (y) (eqv? x y)))])
    y))

(如果您确实想使用
do
,那么您在测试中缺少一对参数,您应该为累加器添加一个绑定。)

使用命名循环的解决方案。(在我看来!)比
do
版本更干净,应该适用于任何R5RS方案:

;; Extracts the sublist of `lst` up to `val`. 
;; If `val` is not found, evaluates to an empty list.
(define (upto val lst)
  (let loop ((res null) (lst lst))
    (cond ((null? lst) null)
          ((eq? val (car lst)) (reverse res))
          (else (loop (cons (car lst) res) (cdr lst))))))

;; Adapts the above procedure to work with vectors.
(define (vector-upto val vec)
  (list->vector (upto val (vector->list vec))))

;; test
(vector-upto 6 #(1 2 3 4 5))
=> #0()
(vector-upto 5 #(1 2 3 4 5))
=> #4(1 2 3 4)
(vector-upto 3 #(1 2 3 4 5))
=> #2(1 2)
(vector-upto 1 #(1 2 3 4 5))
=> #0()

谢谢你的回答。我要做的是在其他值之前将向量中出现的所有值存储在一个列表中。如果我的向量是1234,我传入4,我希望函数返回1233。我试着运行你的代码,收到一个错误,“for/list”是对未定义标识符的引用。但我肯定会研究for循环。所以我最初对你尝试做的事情的猜测是错误的——我修改了它以符合你现在想要的。至于错误,您应该使用“从源代码确定语言”语言,并确保顶部有“
#lang racket
”。(希望您使用的是最新版本。)在Scheme中,Paren并没有走自己的路线。缩进应该足以分隔代码块。如果在每次调用正文之前都有副作用,我不确定此解决方案(使用可选的
let
语法)是否比
do
更清晰。但我认为这是个人偏好的问题。不过,对于你的建议,我建议+1。
;; Extracts the sublist of `lst` up to `val`. 
;; If `val` is not found, evaluates to an empty list.
(define (upto val lst)
  (let loop ((res null) (lst lst))
    (cond ((null? lst) null)
          ((eq? val (car lst)) (reverse res))
          (else (loop (cons (car lst) res) (cdr lst))))))

;; Adapts the above procedure to work with vectors.
(define (vector-upto val vec)
  (list->vector (upto val (vector->list vec))))

;; test
(vector-upto 6 #(1 2 3 4 5))
=> #0()
(vector-upto 5 #(1 2 3 4 5))
=> #4(1 2 3 4)
(vector-upto 3 #(1 2 3 4 5))
=> #2(1 2)
(vector-upto 1 #(1 2 3 4 5))
=> #0()