我遇到了实现 andmap 方案功能-andmap proc的问题。
输出应该是:
现在,我有一个用于andmap func的代码,但是对于一个以上的列表来说,这并不是一件好事。
我的代码:
(define (andmap1 pred lox)
(foldr (lambda (x y) (and x y)) true (map pred lox)))
有人可以帮我吗? 谢谢
答案 0 :(得分:3)
您尝试实现andmap
的方式存在一个概念性问题。它应该是短路评估,这意味着它必须在找到false
值后立即停止,并且返回值是评估输入中最后一个表达式的结果。
这就是为什么(map pred lox)
部分一旦到达(andmap1 positive? '(1 -2 a))
就会因a
示例而失败,并且无论如何foldr
将尝试使用整个输入列表-我们不希望这些事情发生。
考虑到以上考虑因素,再加上对多个输入列表进行操作的要求,解决方案发生了很大变化:
(define (andmap1 pred . lox) ; lox is a variable-length list of lists
(let loop ((lst lox)) ; iterate using a named `let`
(cond ((or (null? lst) (null? (car lst))) ; if the input is empty
true) ; then the result is `true`
((null? (cdar lst)) ; if there's a single element left in sublists
(apply pred (map car lst))) ; return pred applied to all
((not (apply pred (map car lst))) ; if current elements fail pred
false) ; short-circuit and return `false` immediately
(else (loop (map cdr lst)))))) ; advance recursion on all sublists
它按预期工作:
(andmap1 positive? '(1 2 3))
=> #t
(andmap1 positive? '(1 2 a))
=> positive?: contract violation expected: real? given: 'a
(andmap1 positive? '(1 -2 a))
=> #f
(andmap1 + '(1 2 3) '(4 5 6))
=> 9
答案 1 :(得分:0)
这是您编写它的另一种方法,但是请注意,由于使用了foldl
,因此它没有提前退出的行为。如我们所见,实现由map
和and
的折叠组成-
(define (andmap f . ls)
(foldl (lambda (x acc) (and acc x))
#t
(apply map
(lambda xs (apply f xs))
ls)))
(andmap positive? '(1 2 3)) ; #t
(andmap + '(1 2 3) '(4 5 6)) ; 9