我想知道是否可以使用球拍中的内置函数foldl和foldr来编写list-ref函数。基本上,我该如何使用fold和foldr更改这段代码:
(定义(my-list-ref lst n) (如果(零?n) (第一名) (list-ref(rest lst)(-n 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