在我用 JavaScript 编写的方案解释器中,我想修改
some
函数,该函数检查列表中的任何元素是否返回 true
。通过允许传递多个列表的实现。
我有一个 JavaScript 函数
some: doc('some', function some(fn, list) {
typecheck('some', fn, 'function');
typecheck('some', list, ['pair', 'nil']);
if (is_null(list)) {
return false;
} else {
return unpromise(fn(list.car), (value) => {
return value || some(fn, list.cdr);
});
}
}, `(some fn list)
Higher-order function that calls fn on each element of the list.
It stops and returns true when fn returns true for a value.
If none of the values give true, some will return false.
Analogous to Python any(map(fn, list)).`),
我想用Scheme代码替换。
我已经实现了这样的代码:
(define (%some fn lists)
"(%some fn lists)
version of some without typechecking."
(if (or (null? lists) (%some null? lists))
false
(if (apply fn (map car lists))
true
(%some fn (map cdr lists)))))
;; -----------------------------------------------------------------------------
(define (some fn . lists)
"(some fn . lists)
Higher-order function that calls fn on consecutive elements of the list of lists.
It stops and returns true when fn returns true. If none of the values give true,
some will return false. Analogous to Python any(map(fn, list))."
(typecheck "some" fn "function")
(typecheck-args (vector "pair" "nil") "some" lists)
(%some fn lists))
但问题是我无法在
%some
中使用 %some
来检查列表是否为空。它会引发堆栈溢出。
我试图创建一个辅助宏:
(define-macro (%any lists)
`(or ,@lists))
并像这样使用它:
(%any (map null? lists))
但这是完全错误的做法。
我正在搜索我的笔记,发现了我很久以前写的这段代码:
(define-macro (macron m)
(let ((x (gensym)))
`(lambda ,x
(eval `(,',m ,@,x) (interaction-environment)))))
(apply (macron or) (map null? '(() '(x) '())))
#t
将宏映射到函数,但应该有一个简单的方法。
那么,当您需要相同的过程来测试任何列表是否不为空时,您将如何在Scheme中实现
some
/any
过程?
我通过创建辅助函数来检查列表元素是否为空来解决这个问题。
(define (%any-null? lst)
"(%any-null? lst)
Checks if any of elemets in the list is null."
(if (null? lst)
false
(if (null? (car lst))
true
(%any-null? (cdr lst)))))
(define (%some fn lists)
"(%some fn lists)
version of some without typechecking."
(if (or (null? lists) (%any-null? lists))
false
(if (apply fn (map car lists))
true
(%some fn (map cdr lists)))))