在方案中为任意数量的列表实现andmap功能

问题描述 投票:0回答:2

我有一个问题来实现andmap方案函数 - andmap proc

输出应该是:

enter image description here

现在,我有一个andmap func的代码,但它不适合更多的列表。

我的代码:

(define (andmap1 pred lox)
(foldr (lambda (x y) (and x y)) true (map pred lox)))

我的输出:enter image description here

有谁可以帮助我吗?谢谢

scheme racket
2个回答
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

0
投票

这是你可以编写它的另一种方法,但请注意它没有早期退出行为,因为使用了foldl。正如我们所看到的,实施是由mapand的折叠组合而成 -

(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
© www.soinside.com 2019 - 2024. All rights reserved.