我有一个问题来实现andmap方案函数 - andmap proc。
输出应该是:
现在,我有一个andmap func的代码,但它不适合更多的列表。
我的代码:
(define (andmap1 pred lox)
(foldr (lambda (x y) (and x y)) true (map pred lox)))
有谁可以帮助我吗?谢谢
您尝试实施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
这是你可以编写它的另一种方法,但请注意它没有早期退出行为,因为使用了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