球拍:列表引用功能

时间:2019-11-21 17:17:27

标签: functional-programming scheme lisp racket fold

我想知道是否可以使用球拍中的内置函数foldl和foldr来编写list-ref函数。基本上,我该如何使用fold和foldr更改这段代码:

(定义(my-list-ref lst n)   (如果(零?n)       (第一名)       (list-ref(rest lst)(-n 1)))

1 个答案:

答案 0 :(得分:2)

这是一种可能的方式。诀窍是将具有两个值的列表作为累加器传递:第一个是一个标志,告诉您是否找到了该元素,第二个跟踪您当前的索引,我们在每次迭代时都会递增。该标志是必需的,因为我们需要一种说法:停止寻找索引,我们已经找到了它。无论如何,foldl必须使用整个输入列表,因为这就是它的工作原理。

(define (my-list-ref lst n)
  (let ((result
         (foldl (lambda (ele acc)
                  (cond ((first acc) acc)
                        ((= n (second acc)) (list #t ele))
                        (else (list #f (add1 (second acc))))))
                (list #f 0)
                lst)))
    (if (first result)
        (second result)
        (error "index out of bounds"))))

一些测试:

(my-list-ref '(a b c) 0)
=> 'a
(my-list-ref '(a b c) 1)
=> 'b
(my-list-ref '(a b c) 2)
=> 'c

(my-list-ref '() 0)
=> index out of bounds
(my-list-ref '(a b c) -1)
=> index out of bounds
(my-list-ref '(a b c) 3)
=> index out of bounds
相关问题