为什么将map应用于表达式列表,并且仅返回一个布尔值?

问题描述 投票:0回答:1
(define (cart . lists)
  (cond ((null? lists) '())
        ((= (length lists) 1) (map list (first lists)))
        (else
         (append-map (lambda(x)
                       (map (lambda(y) (cons y x))
                            (first lists)))
                     (apply cart (rest lists))))))

(define (numbers n)
   (define (reversed-numbers n)
     (if (= n 0)
         '()
         `(,n . ,(reversed-numbers (- n 1)))))
   (reverse (reversed-numbers n)))

(define (gen-truth n vals)
       (apply cart (map (lambda(x) list vals) (numbers n))))

(gen-truth 2 '(#t #f))  returns: '((#t #t) (#f #t) (#t #f) (#f #f))

(define and-l (lambda x 
    (if (null? x)
        #t
        (if (car x) (apply and-l (cdr x)) #f))))

为什么:(apply map and-l (gen-truth 2 '(#t #f)))

返回'(#f #f)?我希望它为每个包含成对布尔值的子表达式返回一个布尔值。

scheme racket
1个回答
0
投票

第一个问题是and-l过程被破坏。在此,x在传递到过程主体之前被放入列表中。考虑:

scratch.rkt> (define bad-proc (lambda x x))
scratch.rkt> (bad-proc '(#t #f))
'((#t #f))

and-l过程应该测试一个列表是否包含所有真值,而传递给该过程主体的一个确实包含:

scratch.rkt> (and-l-bad '(#t #f))
#t
scratch.rkt> (and-l-bad '(#f #f))
#t
scratch.rkt> (and-l-bad '(#t #t))
#t

这里是and-l的正确版本;注意,不需要apply

(define and-l
  (lambda (x)
    (if (null? x)
        #t
        (and (car x) (and-l (cdr x))))))

测试新过程:

scratch.rkt> (and-l '(#t #f))
#f
scratch.rkt> (and-l '(#f #f))
#f
scratch.rkt> (and-l '(#t #t))
#t

现在and-l可以正常工作,我们将注意力转向:

(apply map and-l (gen-truth 2 '(#t #f)))

同样,这里不需要apply。在这里甚至没有意义(apply map and-l ;....)apply过程将过程和列表作为参数,并将列表的元素用作过程的参数。因此,(apply + '(1 2 3 4))等效于(+ 1 2 3 4)。在当前情况下不需要此功能;所有需要的是mapand-l应用于gen-truth返回的列表中的每个布尔列表:

scratch.rkt> (gen-truth 2 '(#t #f))
'((#t #t) (#f #t) (#t #f) (#f #f))
scratch.rkt> (map and-l (gen-truth 2 '(#t #f)))
'(#t #f #f #f)
© www.soinside.com 2019 - 2024. All rights reserved.